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