1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.launcher3.model;
17 
18 import android.content.Context;
19 import android.content.pm.ApplicationInfo;
20 import android.content.pm.PackageManager;
21 
22 import androidx.annotation.NonNull;
23 
24 import com.android.launcher3.LauncherModel.ModelUpdateTask;
25 import com.android.launcher3.model.data.AppInfo;
26 import com.android.launcher3.model.data.ItemInfo;
27 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
28 import com.android.launcher3.pm.PackageInstallInfo;
29 import com.android.launcher3.util.InstantAppResolver;
30 
31 import java.util.HashSet;
32 import java.util.List;
33 
34 /**
35  * Handles changes due to a sessions updates for a currently installing app.
36  */
37 public class PackageInstallStateChangedTask implements ModelUpdateTask {
38 
39     @NonNull
40     private final PackageInstallInfo mInstallInfo;
41 
PackageInstallStateChangedTask(@onNull final PackageInstallInfo installInfo)42     public PackageInstallStateChangedTask(@NonNull final PackageInstallInfo installInfo) {
43         mInstallInfo = installInfo;
44     }
45 
46     @Override
execute(@onNull ModelTaskController taskController, @NonNull BgDataModel dataModel, @NonNull AllAppsList apps)47     public void execute(@NonNull ModelTaskController taskController, @NonNull BgDataModel dataModel,
48             @NonNull AllAppsList apps) {
49         if (mInstallInfo.state == PackageInstallInfo.STATUS_INSTALLED) {
50             try {
51                 // For instant apps we do not get package-add. Use setting events to update
52                 // any pinned icons.
53                 Context context = taskController.getApp().getContext();
54                 ApplicationInfo ai = context
55                         .getPackageManager().getApplicationInfo(mInstallInfo.packageName, 0);
56                 if (InstantAppResolver.newInstance(context).isInstantApp(ai)) {
57                     taskController.getApp().getModel().newModelCallbacks()
58                             .onPackageAdded(ai.packageName, mInstallInfo.user);
59                 }
60             } catch (PackageManager.NameNotFoundException e) {
61                 // Ignore
62             }
63             // Ignore install success events as they are handled by Package add events.
64             return;
65         }
66 
67         synchronized (apps) {
68             List<AppInfo> updatedAppInfos = apps.updatePromiseInstallInfo(mInstallInfo);
69             if (!updatedAppInfos.isEmpty()) {
70                 for (AppInfo appInfo : updatedAppInfos) {
71                     taskController.scheduleCallbackTask(
72                             c -> c.bindIncrementalDownloadProgressUpdated(appInfo));
73                 }
74             }
75             taskController.bindApplicationsIfNeeded();
76         }
77 
78         synchronized (dataModel) {
79             final HashSet<ItemInfo> updates = new HashSet<>();
80             dataModel.forAllWorkspaceItemInfos(mInstallInfo.user, si -> {
81                 if (si.hasPromiseIconUi()
82                         && mInstallInfo.packageName.equals(si.getTargetPackage())) {
83                     si.setProgressLevel(mInstallInfo);
84                     updates.add(si);
85                 }
86             });
87 
88             for (LauncherAppWidgetInfo widget : dataModel.appWidgets) {
89                 if (widget.providerName.getPackageName().equals(mInstallInfo.packageName)) {
90                     widget.installProgress = mInstallInfo.progress;
91                     updates.add(widget);
92                 }
93             }
94 
95             if (!updates.isEmpty()) {
96                 taskController.scheduleCallbackTask(
97                         callbacks -> callbacks.bindRestoreItemsChange(updates));
98             }
99         }
100     }
101 }
102