• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.ComponentName;
19 import android.content.pm.ApplicationInfo;
20 import android.content.pm.PackageManager;
21 import android.os.Process;
22 
23 import com.android.launcher3.AllAppsList;
24 import com.android.launcher3.AppInfo;
25 import com.android.launcher3.ItemInfo;
26 import com.android.launcher3.LauncherAppState;
27 import com.android.launcher3.LauncherAppWidgetInfo;
28 import com.android.launcher3.LauncherModel.CallbackTask;
29 import com.android.launcher3.LauncherModel.Callbacks;
30 import com.android.launcher3.PromiseAppInfo;
31 import com.android.launcher3.ShortcutInfo;
32 import com.android.launcher3.compat.PackageInstallerCompat;
33 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
34 import com.android.launcher3.util.InstantAppResolver;
35 
36 import java.util.ArrayList;
37 import java.util.HashSet;
38 
39 /**
40  * Handles changes due to a sessions updates for a currently installing app.
41  */
42 public class PackageInstallStateChangedTask extends BaseModelUpdateTask {
43 
44     private final PackageInstallInfo mInstallInfo;
45 
PackageInstallStateChangedTask(PackageInstallInfo installInfo)46     public PackageInstallStateChangedTask(PackageInstallInfo installInfo) {
47         mInstallInfo = installInfo;
48     }
49 
50     @Override
execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps)51     public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
52         if (mInstallInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
53             try {
54                 // For instant apps we do not get package-add. Use setting events to update
55                 // any pinned icons.
56                 ApplicationInfo ai = app.getContext()
57                         .getPackageManager().getApplicationInfo(mInstallInfo.packageName, 0);
58                 if (InstantAppResolver.newInstance(app.getContext()).isInstantApp(ai)) {
59                     app.getModel().onPackageAdded(ai.packageName, Process.myUserHandle());
60                 }
61             } catch (PackageManager.NameNotFoundException e) {
62                 // Ignore
63             }
64             // Ignore install success events as they are handled by Package add events.
65             return;
66         }
67 
68         synchronized (apps) {
69             PromiseAppInfo updated = null;
70             final ArrayList<AppInfo> removed = new ArrayList<>();
71             for (int i=0; i < apps.size(); i++) {
72                 final AppInfo appInfo = apps.get(i);
73                 final ComponentName tgtComp = appInfo.getTargetComponent();
74                 if (tgtComp != null && tgtComp.getPackageName().equals(mInstallInfo.packageName)) {
75                     if (appInfo instanceof PromiseAppInfo) {
76                         final PromiseAppInfo promiseAppInfo = (PromiseAppInfo) appInfo;
77                         if (mInstallInfo.state == PackageInstallerCompat.STATUS_INSTALLING) {
78                             promiseAppInfo.level = mInstallInfo.progress;
79                             updated = promiseAppInfo;
80                         } else if (mInstallInfo.state == PackageInstallerCompat.STATUS_FAILED) {
81                             apps.removePromiseApp(appInfo);
82                             removed.add(appInfo);
83                         }
84                     }
85                 }
86             }
87             if (updated != null) {
88                 final PromiseAppInfo updatedPromiseApp = updated;
89                 scheduleCallbackTask(new CallbackTask() {
90                     @Override
91                     public void execute(Callbacks callbacks) {
92                         callbacks.bindPromiseAppProgressUpdated(updatedPromiseApp);
93                     }
94                 });
95             }
96             if (!removed.isEmpty()) {
97                 scheduleCallbackTask(new CallbackTask() {
98                     @Override
99                     public void execute(Callbacks callbacks) {
100                         callbacks.bindAppInfosRemoved(removed);
101                     }
102                 });
103             }
104         }
105 
106         synchronized (dataModel) {
107             final HashSet<ItemInfo> updates = new HashSet<>();
108             for (ItemInfo info : dataModel.itemsIdMap) {
109                 if (info instanceof ShortcutInfo) {
110                     ShortcutInfo si = (ShortcutInfo) info;
111                     ComponentName cn = si.getTargetComponent();
112                     if (si.hasPromiseIconUi() && (cn != null)
113                             && mInstallInfo.packageName.equals(cn.getPackageName())) {
114                         si.setInstallProgress(mInstallInfo.progress);
115                         if (mInstallInfo.state == PackageInstallerCompat.STATUS_FAILED) {
116                             // Mark this info as broken.
117                             si.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
118                         }
119                         updates.add(si);
120                     }
121                 }
122             }
123 
124             for (LauncherAppWidgetInfo widget : dataModel.appWidgets) {
125                 if (widget.providerName.getPackageName().equals(mInstallInfo.packageName)) {
126                     widget.installProgress = mInstallInfo.progress;
127                     updates.add(widget);
128                 }
129             }
130 
131             if (!updates.isEmpty()) {
132                 scheduleCallbackTask(new CallbackTask() {
133                     @Override
134                     public void execute(Callbacks callbacks) {
135                         callbacks.bindRestoreItemsChange(updates);
136                     }
137                 });
138             }
139         }
140     }
141 }
142