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 
17 package com.android.launcher3.model;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.pm.LauncherApps;
23 import android.os.UserHandle;
24 
25 import com.android.launcher3.LauncherAppState;
26 import com.android.launcher3.LauncherModel;
27 import com.android.launcher3.util.PackageManagerHelper;
28 import com.android.launcher3.util.PackageUserKey;
29 
30 import java.util.ArrayList;
31 import java.util.Set;
32 
33 /**
34  * Helper class to re-query app status when SD-card becomes available.
35  *
36  * During first load, just after reboot, some apps on sdcard might not be available immediately due
37  * to some race conditions in the system. We wait for ACTION_BOOT_COMPLETED and process such
38  * apps again.
39  */
40 public class SdCardAvailableReceiver extends BroadcastReceiver {
41 
42     private final LauncherModel mModel;
43     private final Context mContext;
44     private final Set<PackageUserKey> mPackages;
45 
SdCardAvailableReceiver(LauncherAppState app, Set<PackageUserKey> packages)46     public SdCardAvailableReceiver(LauncherAppState app, Set<PackageUserKey> packages) {
47         mModel = app.getModel();
48         mContext = app.getContext();
49         mPackages = packages;
50     }
51 
52     @Override
onReceive(Context context, Intent intent)53     public void onReceive(Context context, Intent intent) {
54         final LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
55         final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
56         for (PackageUserKey puk : mPackages) {
57             UserHandle user = puk.mUser;
58 
59             final ArrayList<String> packagesRemoved = new ArrayList<>();
60             final ArrayList<String> packagesUnavailable = new ArrayList<>();
61 
62             if (!launcherApps.isPackageEnabled(puk.mPackageName, user)) {
63                 if (pmHelper.isAppOnSdcard(puk.mPackageName, user)) {
64                     packagesUnavailable.add(puk.mPackageName);
65                 } else {
66                     packagesRemoved.add(puk.mPackageName);
67                 }
68             }
69             if (!packagesRemoved.isEmpty()) {
70                 mModel.onPackagesRemoved(user,
71                         packagesRemoved.toArray(new String[packagesRemoved.size()]));
72             }
73             if (!packagesUnavailable.isEmpty()) {
74                 mModel.onPackagesUnavailable(
75                         packagesUnavailable.toArray(new String[packagesUnavailable.size()]),
76                         user, false);
77             }
78         }
79 
80         // Unregister the broadcast receiver, just in case
81         mContext.unregisterReceiver(this);
82     }
83 }
84