1e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler/* 2e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * Copyright (C) 2016 The Android Open Source Project 3e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * 4e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License"); 5e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * you may not use this file except in compliance with the License. 6e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * You may obtain a copy of the License at 7e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * 8e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * http://www.apache.org/licenses/LICENSE-2.0 9e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * 10e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * Unless required by applicable law or agreed to in writing, software 11e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS, 12e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * See the License for the specific language governing permissions and 14e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * limitations under the License 15e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler */ 16e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 17e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerpackage com.android.settingslib.users; 18e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 19e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.app.AppGlobals; 20e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.appwidget.AppWidgetManager; 21e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.Context; 22e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.Intent; 23e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.pm.ApplicationInfo; 24e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.pm.IPackageManager; 25e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.pm.PackageInfo; 26e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.pm.PackageManager; 27e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.pm.ParceledListSlice; 28e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.pm.ResolveInfo; 29e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.content.res.Resources; 30e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.graphics.drawable.Drawable; 31e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.os.RemoteException; 32e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.os.UserHandle; 33e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.os.UserManager; 34e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.text.TextUtils; 35e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.util.Log; 36e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.view.inputmethod.InputMethodInfo; 37e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport android.view.inputmethod.InputMethodManager; 38e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 39e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.ArrayList; 40e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.Collections; 41e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.Comparator; 42e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.HashMap; 43e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.HashSet; 44e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.List; 45e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.Map; 46e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerimport java.util.Set; 47e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 48e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantlerpublic class AppRestrictionsHelper { 49e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private static final boolean DEBUG = false; 50e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private static final String TAG = "AppRestrictionsHelper"; 51e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 52e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private final Context mContext; 53e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private final PackageManager mPackageManager; 54e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private final IPackageManager mIPm; 55e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private final UserManager mUserManager; 56e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private final UserHandle mUser; 57e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private final boolean mRestrictedProfile; 58a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler private boolean mLeanback; 59e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 60e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler HashMap<String,Boolean> mSelectedPackages = new HashMap<>(); 61e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private List<SelectableAppInfo> mVisibleApps; 62e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 63e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public AppRestrictionsHelper(Context context, UserHandle user) { 64e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mContext = context; 65e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mPackageManager = context.getPackageManager(); 66e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mIPm = AppGlobals.getPackageManager(); 67e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mUser = user; 68e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 69e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mRestrictedProfile = mUserManager.getUserInfo(mUser.getIdentifier()).isRestricted(); 70e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 71e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 72e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public void setPackageSelected(String packageName, boolean selected) { 73e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mSelectedPackages.put(packageName, selected); 74e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 75e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 76e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public boolean isPackageSelected(String packageName) { 77e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return mSelectedPackages.get(packageName); 78e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 79e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 80a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler public void setLeanback(boolean isLeanback) { 81a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler mLeanback = isLeanback; 82a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler } 83a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler 84e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public List<SelectableAppInfo> getVisibleApps() { 85e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return mVisibleApps; 86e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 87e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 88e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public void applyUserAppsStates(OnDisableUiForPackageListener listener) { 89e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final int userId = mUser.getIdentifier(); 90e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (!mUserManager.getUserInfo(userId).isRestricted() && userId != UserHandle.myUserId()) { 91e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Log.e(TAG, "Cannot apply application restrictions on another user!"); 92e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return; 93e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 94e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler for (Map.Entry<String,Boolean> entry : mSelectedPackages.entrySet()) { 95e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler String packageName = entry.getKey(); 96e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler boolean enabled = entry.getValue(); 97e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler applyUserAppState(packageName, enabled, listener); 98e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 99e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 100e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 101e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public void applyUserAppState(String packageName, boolean enabled, 102e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler OnDisableUiForPackageListener listener) { 103e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final int userId = mUser.getIdentifier(); 104e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (enabled) { 105e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Enable selected apps 106e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler try { 107e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler ApplicationInfo info = mIPm.getApplicationInfo(packageName, 108e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); 109e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (info == null || !info.enabled 110e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 111e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mIPm.installExistingPackageAsUser(packageName, mUser.getIdentifier()); 112e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (DEBUG) { 113e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Log.d(TAG, "Installing " + packageName); 114e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 115e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 116e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (info != null && (info.privateFlags&ApplicationInfo.PRIVATE_FLAG_HIDDEN) != 0 117e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler && (info.flags&ApplicationInfo.FLAG_INSTALLED) != 0) { 118e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler listener.onDisableUiForPackage(packageName); 119e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mIPm.setApplicationHiddenSettingAsUser(packageName, false, userId); 120e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (DEBUG) { 121e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Log.d(TAG, "Unhiding " + packageName); 122e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 123e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 124e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } catch (RemoteException re) { 125e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Ignore 126e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 127e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } else { 128e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Blacklist all other apps, system or downloaded 129e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler try { 130e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler ApplicationInfo info = mIPm.getApplicationInfo(packageName, 0, userId); 131e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (info != null) { 132e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (mRestrictedProfile) { 133e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mIPm.deletePackageAsUser(packageName, null, mUser.getIdentifier(), 134e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler PackageManager.DELETE_SYSTEM_APP); 135e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (DEBUG) { 136e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Log.d(TAG, "Uninstalling " + packageName); 137e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 138e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } else { 139e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler listener.onDisableUiForPackage(packageName); 140e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mIPm.setApplicationHiddenSettingAsUser(packageName, true, userId); 141e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (DEBUG) { 142e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Log.d(TAG, "Hiding " + packageName); 143e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 144e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 145e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 146e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } catch (RemoteException re) { 147e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Ignore 148e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 149e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 150e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 151e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 152e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public void fetchAndMergeApps() { 153e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mVisibleApps = new ArrayList<>(); 154e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final PackageManager pm = mPackageManager; 155e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final IPackageManager ipm = mIPm; 156e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 157e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final HashSet<String> excludePackages = new HashSet<>(); 158e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler addSystemImes(excludePackages); 159e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 160e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Add launchers 161e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Intent launcherIntent = new Intent(Intent.ACTION_MAIN); 162a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler if (mLeanback) { 163a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler launcherIntent.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER); 164a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler } else { 165a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER); 166a1ae289679a96de4a18fcc4defc8a78c6b149e60Tony Mantler } 167e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler addSystemApps(mVisibleApps, launcherIntent, excludePackages); 168e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 169e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Add widgets 170e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Intent widgetIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); 171e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler addSystemApps(mVisibleApps, widgetIntent, excludePackages); 172e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 173e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler List<ApplicationInfo> installedApps = pm.getInstalledApplications( 174e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler PackageManager.MATCH_UNINSTALLED_PACKAGES); 175e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler for (ApplicationInfo app : installedApps) { 176e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // If it's not installed, skip 177e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if ((app.flags & ApplicationInfo.FLAG_INSTALLED) == 0) continue; 178e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 179e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 180e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler && (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) { 181e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Downloaded app 182e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler SelectableAppInfo info = new SelectableAppInfo(); 183e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.packageName = app.packageName; 184e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.appName = app.loadLabel(pm); 185e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.activityName = info.appName; 186e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.icon = app.loadIcon(pm); 187e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mVisibleApps.add(info); 188e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } else { 189e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler try { 190e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler PackageInfo pi = pm.getPackageInfo(app.packageName, 0); 191e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // If it's a system app that requires an account and doesn't see restricted 192e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // accounts, mark for removal. It might get shown in the UI if it has an icon 193e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // but will still be marked as false and immutable. 194e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (mRestrictedProfile 195e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler && pi.requiredAccountType != null && pi.restrictedAccountType == null) { 196e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mSelectedPackages.put(app.packageName, false); 197e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 198e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } catch (PackageManager.NameNotFoundException re) { 199e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Skip 200e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 201e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 202e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 203e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 204e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Get the list of apps already installed for the user 205e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler List<ApplicationInfo> userApps = null; 206e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler try { 207e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler ParceledListSlice<ApplicationInfo> listSlice = ipm.getInstalledApplications( 208e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler PackageManager.MATCH_UNINSTALLED_PACKAGES, mUser.getIdentifier()); 209e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (listSlice != null) { 210e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler userApps = listSlice.getList(); 211e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 212e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } catch (RemoteException re) { 213e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Ignore 214e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 215e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 216e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (userApps != null) { 217e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler for (ApplicationInfo app : userApps) { 218e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if ((app.flags & ApplicationInfo.FLAG_INSTALLED) == 0) continue; 219e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 220e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 221e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler && (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) { 222e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Downloaded app 223e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler SelectableAppInfo info = new SelectableAppInfo(); 224e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.packageName = app.packageName; 225e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.appName = app.loadLabel(pm); 226e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.activityName = info.appName; 227e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.icon = app.loadIcon(pm); 228e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mVisibleApps.add(info); 229e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 230e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 231e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 232e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 233e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Sort the list of visible apps 234e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Collections.sort(mVisibleApps, new AppLabelComparator()); 235e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 236e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Remove dupes 237e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Set<String> dedupPackageSet = new HashSet<String>(); 238e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler for (int i = mVisibleApps.size() - 1; i >= 0; i--) { 239e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler SelectableAppInfo info = mVisibleApps.get(i); 240e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (DEBUG) Log.i(TAG, info.toString()); 241e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler String both = info.packageName + "+" + info.activityName; 242e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (!TextUtils.isEmpty(info.packageName) 243e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler && !TextUtils.isEmpty(info.activityName) 244e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler && dedupPackageSet.contains(both)) { 245e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mVisibleApps.remove(i); 246e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } else { 247e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler dedupPackageSet.add(both); 248e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 249e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 250e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 251e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Establish master/slave relationship for entries that share a package name 252e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler HashMap<String,SelectableAppInfo> packageMap = new HashMap<String,SelectableAppInfo>(); 253e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler for (SelectableAppInfo info : mVisibleApps) { 254e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (packageMap.containsKey(info.packageName)) { 255e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.masterEntry = packageMap.get(info.packageName); 256e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } else { 257e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler packageMap.put(info.packageName, info); 258e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 259e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 260e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 261e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 262e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler /** 263e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * Find all pre-installed input methods that are marked as default 264e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * and add them to an exclusion list so that they aren't 265e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * presented to the user for toggling. 266e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * Don't add non-default ones, as they may include other stuff that we 267e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * don't need to auto-include. 268e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * @param excludePackages the set of package names to append to 269e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler */ 270e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private void addSystemImes(Set<String> excludePackages) { 271e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler InputMethodManager imm = (InputMethodManager) 272e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 273e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler List<InputMethodInfo> imis = imm.getInputMethodList(); 274e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler for (InputMethodInfo imi : imis) { 275e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler try { 276e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (imi.isDefault(mContext) && isSystemPackage(imi.getPackageName())) { 277e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler excludePackages.add(imi.getPackageName()); 278e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 279e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } catch (Resources.NotFoundException rnfe) { 280e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Not default 281e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 282e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 283e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 284e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 285e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler /** 286e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * Add system apps that match an intent to the list, excluding any packages in the exclude list. 287e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * @param visibleApps list of apps to append the new list to 288e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * @param intent the intent to match 289e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler * @param excludePackages the set of package names to be excluded, since they're required 290e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler */ 291e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private void addSystemApps(List<SelectableAppInfo> visibleApps, Intent intent, 292e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler Set<String> excludePackages) { 293e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final PackageManager pm = mPackageManager; 294e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler List<ResolveInfo> launchableApps = pm.queryIntentActivities(intent, 295e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES); 296e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler for (ResolveInfo app : launchableApps) { 297e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (app.activityInfo != null && app.activityInfo.applicationInfo != null) { 298e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final String packageName = app.activityInfo.packageName; 299e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler int flags = app.activityInfo.applicationInfo.flags; 300e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0 301e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler || (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { 302e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // System app 303e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Skip excluded packages 304e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (excludePackages.contains(packageName)) continue; 305e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler int enabled = pm.getApplicationEnabledSetting(packageName); 306e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED 307e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler || enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { 308e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Check if the app is already enabled for the target user 309e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler ApplicationInfo targetUserAppInfo = getAppInfoForUser(packageName, 310e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 0, mUser); 311e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (targetUserAppInfo == null 312e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler || (targetUserAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 313e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler continue; 314e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 315e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 316e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler SelectableAppInfo info = new SelectableAppInfo(); 317e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.packageName = app.activityInfo.packageName; 318e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.appName = app.activityInfo.applicationInfo.loadLabel(pm); 319e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.icon = app.activityInfo.loadIcon(pm); 320e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler info.activityName = app.activityInfo.loadLabel(pm); 321e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (info.activityName == null) info.activityName = info.appName; 322e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 323e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler visibleApps.add(info); 324e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 325e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 326e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 327e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 328e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 329e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private boolean isSystemPackage(String packageName) { 330e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler try { 331e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0); 332e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if (pi.applicationInfo == null) return false; 333e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler final int flags = pi.applicationInfo.flags; 334e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0 335e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler || (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { 336e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return true; 337e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 338e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } catch (PackageManager.NameNotFoundException nnfe) { 339e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler // Missing package? 340e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 341e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return false; 342e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 343e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 344e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private ApplicationInfo getAppInfoForUser(String packageName, int flags, UserHandle user) { 345e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler try { 346e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return mIPm.getApplicationInfo(packageName, flags, user.getIdentifier()); 347e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } catch (RemoteException re) { 348e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return null; 349e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 350e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 351e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 352e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public interface OnDisableUiForPackageListener { 353e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler void onDisableUiForPackage(String packageName); 354e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 355e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 356e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public static class SelectableAppInfo { 357e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public String packageName; 358e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public CharSequence appName; 359e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public CharSequence activityName; 360e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public Drawable icon; 361e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public SelectableAppInfo masterEntry; 362e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 363e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler @Override 364e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public String toString() { 365e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return packageName + ": appName=" + appName + "; activityName=" + activityName 366e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler + "; icon=" + icon + "; masterEntry=" + masterEntry; 367e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 368e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 369e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 370e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler private static class AppLabelComparator implements Comparator<SelectableAppInfo> { 371e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler 372e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler @Override 373e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler public int compare(SelectableAppInfo lhs, SelectableAppInfo rhs) { 374e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler String lhsLabel = lhs.activityName.toString(); 375e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler String rhsLabel = rhs.activityName.toString(); 376e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler return lhsLabel.toLowerCase().compareTo(rhsLabel.toLowerCase()); 377e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 378e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler } 379e662ca6b5ec066384d1082fd3f43d50cdea37c68Tony Mantler} 380