1/*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "gallery_ability_slice.h"
17#include "ability_env.h"
18#include "ability_manager.h"
19#include "picture_ability_slice.h"
20
21#include "gfx_utils/file.h"
22#include "securec.h"
23
24namespace OHOS {
25REGISTER_AS(GalleryAbilitySlice)
26
27GalleryAbilitySlice::~GalleryAbilitySlice()
28{
29    printf("~GalleryAbilitySlice() | start \n");
30    Clear();
31    printf("~GalleryAbilitySlice() | end \n");
32}
33
34void GalleryAbilitySlice::Clear()
35{
36    printf("GalleryAbilitySlice::Clear() | start \n");
37    if (backIcon_ != nullptr) {
38        delete backIcon_;
39        backIcon_ = nullptr;
40    }
41    if (backIconListener_ != nullptr) {
42        delete backIconListener_;
43        backIconListener_ = nullptr;
44    }
45    if (deleteClickListener_ != nullptr) {
46        delete deleteClickListener_;
47        deleteClickListener_ = nullptr;
48    }
49    if (backArea_ != nullptr) {
50        delete backArea_;
51        backArea_ = nullptr;
52    }
53    if (titleLabel_ != nullptr) {
54        delete titleLabel_;
55        titleLabel_ = nullptr;
56    }
57    if (deleteLabel_ != nullptr) {
58        delete deleteLabel_;
59        deleteLabel_ = nullptr;
60    }
61
62    ClearThumb();
63
64    if (rootView_ != nullptr) {
65        RootView::DestroyWindowRootView(rootView_);
66        rootView_ = nullptr;
67    }
68    printf("GalleryAbilitySlice::Clear() | end \n");
69}
70
71void GalleryAbilitySlice::ClearThumb()
72{
73    printf("GalleryAbilitySlice::ClearThumb() | start \n");
74    if (picContainer_ != nullptr) {
75        delete picContainer_;
76        picContainer_ = nullptr;
77    }
78    if (picList_ != nullptr) {
79        ClearPictureList(picList_);
80        delete picList_;
81        picList_ = nullptr;
82    }
83    for (uint16_t i = 0; i < pictureCount_; i++) {
84        if (pictureName_[i] != nullptr) {
85            delete[] pictureName_[i];
86            pictureName_[i] = nullptr;
87        }
88    }
89    for (uint16_t i = 0; i < pictureOnClickListenerCount_; i++) {
90        if (pictureOnClickListener_[i] != nullptr) {
91            delete pictureOnClickListener_[i];
92            pictureOnClickListener_[i] = nullptr;
93        }
94    }
95    pictureCount_ = 0;
96    pictureOnClickListenerCount_ = 0;
97    printf("GalleryAbilitySlice::ClearThumb() | end \n");
98}
99
100void GalleryAbilitySlice::ClearPictureList(const UIView* view)
101{
102    printf("GalleryAbilitySlice::ClearPictureList() | start \n");
103    if (view == nullptr || !(view->IsViewGroup())) {
104        return;
105    }
106    UIView* child = static_cast<const UIViewGroup*>(view)->GetChildrenHead();
107    UIView* childNext = nullptr;
108    while (child != nullptr) {
109        childNext = child->GetNextSibling();
110        if (child->IsViewGroup()) {
111            ClearPictureList(child);
112        }
113        delete child;
114        child = childNext;
115    }
116    printf("GalleryAbilitySlice::ClearPictureList() | end \n");
117}
118
119void GalleryAbilitySlice::InitTitle()
120{
121    printf("GalleryAbilitySlice::InitTitle | start \n");
122    backIcon_ = new UIImageView();
123    backIcon_->SetPosition(BACK_ICON_POSITION_X, BACK_ICON_POSITION_Y);
124    backIcon_->SetSrc(backIconAbsolutePath);
125    backIcon_->SetTouchable(true);
126
127    backArea_ = new UIViewGroup();
128    backArea_->SetPosition(0, 0, LABEL_POSITION_X, LABEL_HEIGHT);
129    backArea_->SetStyle(STYLE_BACKGROUND_OPA, 0);
130    backArea_->SetTouchable(true);
131
132    auto onClick = [this] (UIView& view, const Event& event) -> bool {
133        printf("############  Next AS enter   #############\n");
134        TerminateAbility();
135        printf("############  Next AS exit   #############\n");
136        return true;
137    };
138    backIconListener_ = new EventListener(onClick, nullptr);
139    backIcon_->SetOnClickListener(backIconListener_);
140    backArea_->SetOnClickListener(backIconListener_);
141
142    titleLabel_ = new UILabel();
143    titleLabel_->SetPosition(LABEL_POSITION_X, LABEL_POSITION_Y, LABEL_WIDTH, LABEL_HEIGHT);
144    titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
145    titleLabel_->SetFont(FONT_NAME, GALLERY_FONT_SIZE);
146    titleLabel_->SetText("照片");
147
148    deleteLabel_ = new UILabel();
149    deleteLabel_->SetPosition(ROOT_VIEW_WIDTH - DELETE_LABEL_WIDTH, LABEL_POSITION_Y,
150                              DELETE_LABEL_WIDTH, LABEL_HEIGHT);
151    deleteLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT,
152                           UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
153    deleteLabel_->SetFont(FONT_NAME, GALLERY_DELETE_FONT_SIZE);
154    deleteLabel_->SetText("全部删除");
155    deleteLabel_->SetTouchable(true);
156    auto deleteClick = [this] (UIView& view, const Event& event) -> bool {
157        printf("############  DeleteAllData click enter #############\n");
158        DeleteAllData();
159        printf("############  DeleteAllData click exit  #############\n");
160        return true;
161    };
162    deleteClickListener_ = new EventListener(deleteClick, nullptr);
163    deleteLabel_->SetOnClickListener(deleteClickListener_);
164
165    backArea_->Add(backIcon_);
166    rootView_->Add(backArea_);
167    rootView_->Add(titleLabel_);
168    rootView_->Add(deleteLabel_);
169}
170
171void GalleryAbilitySlice::InitPictureList()
172{
173    printf("GalleryAbilitySlice::InitPictureList | start \n");
174    picContainer_ = new UIScrollView();
175    picContainer_->SetPosition(0, LABEL_POSITION_Y + LABEL_HEIGHT);
176    picContainer_->Resize(ROOT_VIEW_WIDTH, (THUMBNAIL_RESOLUTION_Y + THUMBNAIL_SPACE) * THUMBNAIL_COLUMN);
177    picContainer_->SetStyle(STYLE_BACKGROUND_OPA, 0);
178    rootView_->Add(picContainer_);
179
180    picList_ = new UIViewGroup();
181    picList_->SetPosition(0, 0, ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT);
182    picList_->SetStyle(STYLE_BACKGROUND_OPA, 0);
183
184    int16_t numInLine = (ROOT_VIEW_WIDTH + THUMBNAIL_SPACE) / (THUMBNAIL_RESOLUTION_X + THUMBNAIL_SPACE);
185    int16_t offset = ((ROOT_VIEW_WIDTH + THUMBNAIL_SPACE) % (THUMBNAIL_RESOLUTION_X + THUMBNAIL_SPACE)) / 2; // 2: half
186    AddAllPictures(Point { offset, 0 }, numInLine);
187
188    int16_t totalHeight = (pictureCount_ / numInLine) * (THUMBNAIL_RESOLUTION_Y + THUMBNAIL_SPACE);
189    if ((pictureCount_ % numInLine) != 0) {
190        totalHeight += THUMBNAIL_RESOLUTION_Y + THUMBNAIL_SPACE;
191    }
192    picList_->Resize(ROOT_VIEW_WIDTH, totalHeight);
193    printf("------------ totalHeight : %d ------------", totalHeight);
194    picContainer_->Add(picList_);
195}
196
197void GalleryAbilitySlice::AddAllPictures(const Point& pos, int16_t numInLine)
198{
199    printf("GalleryAbilitySlice::AddAllPictures | start | %d\n", numInLine);
200    Point imagePos = pos;
201    DIR* drip = opendir(THUMBNAIL_DIRECTORY);
202    if (drip == nullptr) {
203        return;
204    }
205    struct dirent* info = nullptr;
206    while ((info = readdir(drip)) != nullptr  && pictureCount_ < MAX_PICTURE_COUNT) {
207        uint16_t imageNameLen = static_cast<uint16_t>(strlen(info->d_name));
208        if (imageNameLen > MAX_PATH_LENGTH || (strcmp(info->d_name, ".") == 0) || (strcmp(info->d_name, "..") == 0)) {
209            printf("GalleryAbilitySlice::AddAllPictures | imageNameLen > MAX_PATH_LENGTH | %d\n", imageNameLen);
210            continue;
211        }
212        char* imageName = new char[imageNameLen + 1]();
213        memcpy_s(imageName, imageNameLen + 1, info->d_name, imageNameLen + 1);
214        pictureName_[pictureCount_] = imageName;
215        pictureCount_++;
216
217        uint16_t pathLen = static_cast<uint16_t>(strlen(THUMBNAIL_DIRECTORY)) + imageNameLen + 1;
218        if (pathLen > MAX_PATH_LENGTH) {
219            printf("GalleryAbilitySlice::AddAllPictures | pathLen > MAX_PATH_LENGTH | %d\n", pathLen);
220            continue;
221        }
222        char* imagePath = new char[pathLen + 1]();
223        if (sprintf_s(imagePath, pathLen + 1, "%s/%s", THUMBNAIL_DIRECTORY, info->d_name) < 0) {
224            printf("GalleryAbilitySlice::AddAllPictures | sprintf_s error\n");
225            delete[] imagePath;
226            continue;
227        }
228
229        picList_->Add(CreateImageItem(imagePos, imageName, imagePath));
230        delete[] imagePath;
231
232        if ((pictureCount_ % numInLine) == 0) {
233            imagePos.x = pos.x;
234            imagePos.y += THUMBNAIL_RESOLUTION_Y + THUMBNAIL_SPACE;
235        } else {
236            imagePos.x += THUMBNAIL_RESOLUTION_X + THUMBNAIL_SPACE;
237        }
238    }
239    delete info;
240    closedir(drip);
241}
242
243UIView* GalleryAbilitySlice::CreateImageItem(const Point& pos, const char* imageName, const char* imagePath)
244{
245    UIImageView* imageView = new UIImageView();
246    imageView->SetAutoEnable(false);
247    imageView->Resize(THUMBNAIL_RESOLUTION_X, THUMBNAIL_RESOLUTION_Y);
248    imageView->SetSrc(imagePath);
249    pictureOnClickListener_[pictureOnClickListenerCount_] = GetImageClickListener(imageName);
250    imageView->SetOnClickListener(pictureOnClickListener_[pictureOnClickListenerCount_++]);
251    imageView->SetTouchable(true);
252
253    if (strncmp(imageName, PHOTO_PREFIX, strlen(PHOTO_PREFIX)) == 0) {
254        imageView->SetPosition(pos.x, pos.y);
255        return imageView;
256    }
257    imageView->SetPosition(0, 0);
258
259    UIViewGroup* imageItem = new UIViewGroup();
260    imageItem->SetStyle(STYLE_BACKGROUND_OPA, 0);
261    imageItem->SetPosition(pos.x, pos.y, THUMBNAIL_RESOLUTION_X, THUMBNAIL_RESOLUTION_Y);
262    imageItem->SetTouchable(true);
263    imageItem->SetOnClickListener(imageView->GetOnClickListener());
264
265    UIImageView* videoTag = new UIImageView();
266    videoTag->SetPosition(VIDEO_TAG_POSITION_X, VIDEO_TAG_POSITION_Y);
267    videoTag->SetSrc(videoTagIconAbsolutePath);
268    videoTag->SetTouchable(true);
269    videoTag->SetOnClickListener(imageView->GetOnClickListener());
270
271    imageItem->Add(imageView);
272    imageItem->Add(videoTag);
273
274    return imageItem;
275}
276
277EventListener* GalleryAbilitySlice::GetImageClickListener(const char* path)
278{
279    auto onClick = [this, path] (UIView& view, const Event& event) -> bool {
280        printf("############  Next AS enter   #############\n");
281        Want wantData = { nullptr };
282        printf("------- imagePath: %s \n", path);
283        bool ret = SetWantData(&wantData, path, strlen(path) + 1);
284        if (!ret) {
285            printf("############  SetWantData error   #############\n");
286            return ret;
287        }
288        AbilitySlice* nextSlice = nullptr;
289        if (strncmp(path, PHOTO_PREFIX, strlen(PHOTO_PREFIX)) == 0) {
290            printf("--------- enter PictureAbilitySlice \n");
291            nextSlice = AbilityLoader::GetInstance().GetAbilitySliceByName("PictureAbilitySlice");
292        } else {
293            printf("--------- enter PlayerAbilitySlice \n");
294            nextSlice = AbilityLoader::GetInstance().GetAbilitySliceByName("PlayerAbilitySlice");
295        }
296        if (nextSlice == nullptr) {
297            printf("undefined nextSlice\n");
298        } else {
299            Present(*nextSlice, wantData);
300        }
301        printf("############  Next AS exit   #############\n");
302        return true;
303    };
304    return new EventListener(onClick, nullptr);
305}
306
307void GalleryAbilitySlice::DeleteAllData()
308{
309    picContainer_->Invalidate();
310    rootView_->Remove(picContainer_);
311    ClearThumb();
312
313    DeleteAllFilesInDir(THUMBNAIL_DIRECTORY);
314    DeleteAllFilesInDir(PHOTO_DIRECTORY);
315    DeleteAllFilesInDir(VIDEO_SOURCE_DIRECTORY);
316
317    InitPictureList();
318}
319
320void GalleryAbilitySlice::DeleteAllFilesInDir(const char* path)
321{
322    DIR* drip = opendir(path);
323    if (drip == nullptr) {
324        return;
325    }
326    struct dirent* info = nullptr;
327    while ((info = readdir(drip)) != nullptr) {
328        uint16_t fileNameLen = static_cast<uint16_t>(strlen(info->d_name));
329        uint16_t pathLen = static_cast<uint16_t>(strlen(path)) + fileNameLen + 1;
330        if (pathLen > MAX_PATH_LENGTH) {
331            printf("GalleryAbilitySlice::AddAllPictures | pathLen > MAX_PATH_LENGTH | %d\n", pathLen);
332            continue;
333        }
334        char* filePath = new char[pathLen + 1]();
335        if (sprintf_s(filePath, pathLen + 1, "%s/%s", path, info->d_name) < 0) {
336            printf("GalleryAbilitySlice::AddAllPictures | sprintf_s error\n");
337            delete[] filePath;
338            continue;
339        }
340        if (unlink(filePath) != 0) {
341            printf("unlink file error | %s\n", filePath);
342        }
343        delete[] filePath;
344    }
345    delete info;
346    closedir(drip);
347    printf("GalleryAbilitySlice::DeleteAllFilesInDir() | success | %s\n", path);
348}
349
350void GalleryAbilitySlice::OnStart(const Want &want)
351{
352    AbilitySlice::OnStart(want);
353
354    rootView_ = RootView::GetWindowRootView();
355    rootView_->SetPosition(ROOT_VIEW_POSITION_X, ROOT_VIEW_POSITION_Y);
356    rootView_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT);
357    rootView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
358
359    const char* pathHeader = GetSrcPath();
360    if (sprintf_s(backIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, BACK_ICON_PATH) < 0) {
361        printf("GalleryAbilitySlice::OnStart | backIconAbsolutePath error");
362        return;
363    }
364    if (sprintf_s(videoTagIconAbsolutePath, MAX_PATH_LENGTH, "%s%s", pathHeader, VIDEO_TAG_ICON_PATH) < 0) {
365        printf("GalleryAbilitySlice::OnStart | videoTagIconAbsolutePath error");
366        return;
367    }
368
369    InitTitle();
370    InitPictureList();
371    SetUIContent(rootView_);
372}
373
374void GalleryAbilitySlice::OnInactive()
375{
376    printf("GalleryAbilitySlice::OnInactive\n");
377    AbilitySlice::OnInactive();
378}
379
380void GalleryAbilitySlice::OnActive(const Want &want)
381{
382    printf("GalleryAbilitySlice::OnActive\n");
383    AbilitySlice::OnActive(want);
384}
385
386void GalleryAbilitySlice::OnBackground()
387{
388    printf("GalleryAbilitySlice::OnBackground\n");
389    AbilitySlice::OnBackground();
390}
391
392void GalleryAbilitySlice::OnStop()
393{
394    printf("GalleryAbilitySlice::OnStop\n");
395    AbilitySlice::OnStop();
396    Clear();
397}
398}