1ed13187a745866483139e2878037e1f8427ce567Kenny Guy/* 2ed13187a745866483139e2878037e1f8427ce567Kenny Guy * Copyright (C) 2014 The Android Open Source Project 3ed13187a745866483139e2878037e1f8427ce567Kenny Guy * 4ed13187a745866483139e2878037e1f8427ce567Kenny Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5ed13187a745866483139e2878037e1f8427ce567Kenny Guy * you may not use this file except in compliance with the License. 6ed13187a745866483139e2878037e1f8427ce567Kenny Guy * You may obtain a copy of the License at 7ed13187a745866483139e2878037e1f8427ce567Kenny Guy * 8ed13187a745866483139e2878037e1f8427ce567Kenny Guy * http://www.apache.org/licenses/LICENSE-2.0 9ed13187a745866483139e2878037e1f8427ce567Kenny Guy * 10ed13187a745866483139e2878037e1f8427ce567Kenny Guy * Unless required by applicable law or agreed to in writing, software 11ed13187a745866483139e2878037e1f8427ce567Kenny Guy * distributed under the License is distributed on an "AS IS" BASIS, 12ed13187a745866483139e2878037e1f8427ce567Kenny Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ed13187a745866483139e2878037e1f8427ce567Kenny Guy * See the License for the specific language governing permissions and 14ed13187a745866483139e2878037e1f8427ce567Kenny Guy * limitations under the License. 15ed13187a745866483139e2878037e1f8427ce567Kenny Guy */ 16ed13187a745866483139e2878037e1f8427ce567Kenny Guy 17ed13187a745866483139e2878037e1f8427ce567Kenny Guypackage com.android.launcher3.compat; 18ed13187a745866483139e2878037e1f8427ce567Kenny Guy 19ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.BroadcastReceiver; 20ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.ComponentName; 21ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.Context; 22ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.Intent; 23ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.IntentFilter; 24ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.pm.ActivityInfo; 25cf5d24b21aaff1b6b524874f4609e0c7ebd48458Sunny Goyalimport android.content.pm.PackageInfo; 26ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.pm.PackageManager; 27ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.pm.PackageManager.NameNotFoundException; 28ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.content.pm.ResolveInfo; 29ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.graphics.Rect; 30f07af7b77de0319355e228e8630824d924522d78Kenny Guyimport android.net.Uri; 31ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.os.Build; 32ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport android.os.Bundle; 33f07af7b77de0319355e228e8630824d924522d78Kenny Guyimport android.provider.Settings; 34ed13187a745866483139e2878037e1f8427ce567Kenny Guy 35ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport java.util.ArrayList; 36ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport java.util.List; 37ed13187a745866483139e2878037e1f8427ce567Kenny Guy 38f07af7b77de0319355e228e8630824d924522d78Kenny Guy/** 39f07af7b77de0319355e228e8630824d924522d78Kenny Guy * Version of {@link LauncherAppsCompat} for devices with API level 16. 40f07af7b77de0319355e228e8630824d924522d78Kenny Guy * Devices Pre-L don't support multiple profiles in one launcher so 41f07af7b77de0319355e228e8630824d924522d78Kenny Guy * user parameters are ignored and all methods operate on the current user. 42f07af7b77de0319355e228e8630824d924522d78Kenny Guy */ 43ed13187a745866483139e2878037e1f8427ce567Kenny Guypublic class LauncherAppsCompatV16 extends LauncherAppsCompat { 44ed13187a745866483139e2878037e1f8427ce567Kenny Guy 45ed13187a745866483139e2878037e1f8427ce567Kenny Guy private PackageManager mPm; 46ed13187a745866483139e2878037e1f8427ce567Kenny Guy private Context mContext; 47c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy private List<OnAppsChangedCallbackCompat> mCallbacks 48c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy = new ArrayList<OnAppsChangedCallbackCompat>(); 49ed13187a745866483139e2878037e1f8427ce567Kenny Guy private PackageMonitor mPackageMonitor; 50ed13187a745866483139e2878037e1f8427ce567Kenny Guy 51ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherAppsCompatV16(Context context) { 52ed13187a745866483139e2878037e1f8427ce567Kenny Guy mPm = context.getPackageManager(); 53ed13187a745866483139e2878037e1f8427ce567Kenny Guy mContext = context; 54ed13187a745866483139e2878037e1f8427ce567Kenny Guy mPackageMonitor = new PackageMonitor(); 55ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 56ed13187a745866483139e2878037e1f8427ce567Kenny Guy 57ed13187a745866483139e2878037e1f8427ce567Kenny Guy public List<LauncherActivityInfoCompat> getActivityList(String packageName, 58ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user) { 59ed13187a745866483139e2878037e1f8427ce567Kenny Guy final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 60ed13187a745866483139e2878037e1f8427ce567Kenny Guy mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 61ed13187a745866483139e2878037e1f8427ce567Kenny Guy mainIntent.setPackage(packageName); 62ed13187a745866483139e2878037e1f8427ce567Kenny Guy List<ResolveInfo> infos = mPm.queryIntentActivities(mainIntent, 0); 63ed13187a745866483139e2878037e1f8427ce567Kenny Guy List<LauncherActivityInfoCompat> list = 64ed13187a745866483139e2878037e1f8427ce567Kenny Guy new ArrayList<LauncherActivityInfoCompat>(infos.size()); 65ed13187a745866483139e2878037e1f8427ce567Kenny Guy for (ResolveInfo info : infos) { 66ed13187a745866483139e2878037e1f8427ce567Kenny Guy list.add(new LauncherActivityInfoCompatV16(mContext, info)); 67ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 68ed13187a745866483139e2878037e1f8427ce567Kenny Guy return list; 69ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 70ed13187a745866483139e2878037e1f8427ce567Kenny Guy 71ed13187a745866483139e2878037e1f8427ce567Kenny Guy public LauncherActivityInfoCompat resolveActivity(Intent intent, UserHandleCompat user) { 72ed13187a745866483139e2878037e1f8427ce567Kenny Guy ResolveInfo info = mPm.resolveActivity(intent, 0); 73ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (info != null) { 74ed13187a745866483139e2878037e1f8427ce567Kenny Guy return new LauncherActivityInfoCompatV16(mContext, info); 75ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 76ed13187a745866483139e2878037e1f8427ce567Kenny Guy return null; 77ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 78ed13187a745866483139e2878037e1f8427ce567Kenny Guy 79c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void startActivityForProfile(ComponentName component, UserHandleCompat user, 80c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy Rect sourceBounds, Bundle opts) { 81ed13187a745866483139e2878037e1f8427ce567Kenny Guy Intent launchIntent = new Intent(Intent.ACTION_MAIN); 82ed13187a745866483139e2878037e1f8427ce567Kenny Guy launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); 83ed13187a745866483139e2878037e1f8427ce567Kenny Guy launchIntent.setComponent(component); 84ed13187a745866483139e2878037e1f8427ce567Kenny Guy launchIntent.setSourceBounds(sourceBounds); 85ed13187a745866483139e2878037e1f8427ce567Kenny Guy launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 86ed13187a745866483139e2878037e1f8427ce567Kenny Guy mContext.startActivity(launchIntent, opts); 87ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 88ed13187a745866483139e2878037e1f8427ce567Kenny Guy 89f07af7b77de0319355e228e8630824d924522d78Kenny Guy public void showAppDetailsForProfile(ComponentName component, UserHandleCompat user) { 90f07af7b77de0319355e228e8630824d924522d78Kenny Guy String packageName = component.getPackageName(); 91f07af7b77de0319355e228e8630824d924522d78Kenny Guy Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, 92f07af7b77de0319355e228e8630824d924522d78Kenny Guy Uri.fromParts("package", packageName, null)); 93f07af7b77de0319355e228e8630824d924522d78Kenny Guy intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | 94f07af7b77de0319355e228e8630824d924522d78Kenny Guy Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 95f07af7b77de0319355e228e8630824d924522d78Kenny Guy mContext.startActivity(intent, null); 96f07af7b77de0319355e228e8630824d924522d78Kenny Guy } 97f07af7b77de0319355e228e8630824d924522d78Kenny Guy 98c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public synchronized void addOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) { 99c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy if (callback != null && !mCallbacks.contains(callback)) { 100c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy mCallbacks.add(callback); 101c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy if (mCallbacks.size() == 1) { 102ed13187a745866483139e2878037e1f8427ce567Kenny Guy registerForPackageIntents(); 103ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 104ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 105ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 106ed13187a745866483139e2878037e1f8427ce567Kenny Guy 107c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public synchronized void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat callback) { 108c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy mCallbacks.remove(callback); 109c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy if (mCallbacks.size() == 0) { 110ed13187a745866483139e2878037e1f8427ce567Kenny Guy unregisterForPackageIntents(); 111ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 112ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 113ed13187a745866483139e2878037e1f8427ce567Kenny Guy 114ed13187a745866483139e2878037e1f8427ce567Kenny Guy public boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user) { 115ed13187a745866483139e2878037e1f8427ce567Kenny Guy try { 116ed13187a745866483139e2878037e1f8427ce567Kenny Guy PackageInfo info = mPm.getPackageInfo(packageName, 0); 117ed13187a745866483139e2878037e1f8427ce567Kenny Guy return info != null && info.applicationInfo.enabled; 118ed13187a745866483139e2878037e1f8427ce567Kenny Guy } catch (NameNotFoundException e) { 119ed13187a745866483139e2878037e1f8427ce567Kenny Guy return false; 120ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 121ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 122ed13187a745866483139e2878037e1f8427ce567Kenny Guy 123ed13187a745866483139e2878037e1f8427ce567Kenny Guy public boolean isActivityEnabledForProfile(ComponentName component, UserHandleCompat user) { 124ed13187a745866483139e2878037e1f8427ce567Kenny Guy try { 125ed13187a745866483139e2878037e1f8427ce567Kenny Guy ActivityInfo info = mPm.getActivityInfo(component, 0); 126ed13187a745866483139e2878037e1f8427ce567Kenny Guy return info != null && info.isEnabled(); 127ed13187a745866483139e2878037e1f8427ce567Kenny Guy } catch (NameNotFoundException e) { 128ed13187a745866483139e2878037e1f8427ce567Kenny Guy return false; 129ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 130ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 131ed13187a745866483139e2878037e1f8427ce567Kenny Guy 132ed13187a745866483139e2878037e1f8427ce567Kenny Guy private void unregisterForPackageIntents() { 133ed13187a745866483139e2878037e1f8427ce567Kenny Guy mContext.unregisterReceiver(mPackageMonitor); 134ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 135ed13187a745866483139e2878037e1f8427ce567Kenny Guy 136ed13187a745866483139e2878037e1f8427ce567Kenny Guy private void registerForPackageIntents() { 137ed13187a745866483139e2878037e1f8427ce567Kenny Guy IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 138ed13187a745866483139e2878037e1f8427ce567Kenny Guy filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 139ed13187a745866483139e2878037e1f8427ce567Kenny Guy filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 140ed13187a745866483139e2878037e1f8427ce567Kenny Guy filter.addDataScheme("package"); 141ed13187a745866483139e2878037e1f8427ce567Kenny Guy mContext.registerReceiver(mPackageMonitor, filter); 142ed13187a745866483139e2878037e1f8427ce567Kenny Guy filter = new IntentFilter(); 143ed13187a745866483139e2878037e1f8427ce567Kenny Guy filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 144ed13187a745866483139e2878037e1f8427ce567Kenny Guy filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 145ed13187a745866483139e2878037e1f8427ce567Kenny Guy mContext.registerReceiver(mPackageMonitor, filter); 146ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 147ed13187a745866483139e2878037e1f8427ce567Kenny Guy 148c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy private synchronized List<OnAppsChangedCallbackCompat> getCallbacks() { 149c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy return new ArrayList<OnAppsChangedCallbackCompat>(mCallbacks); 150ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 151ed13187a745866483139e2878037e1f8427ce567Kenny Guy 152ed13187a745866483139e2878037e1f8427ce567Kenny Guy private class PackageMonitor extends BroadcastReceiver { 153ed13187a745866483139e2878037e1f8427ce567Kenny Guy public void onReceive(Context context, Intent intent) { 154ed13187a745866483139e2878037e1f8427ce567Kenny Guy final String action = intent.getAction(); 155ed13187a745866483139e2878037e1f8427ce567Kenny Guy final UserHandleCompat user = UserHandleCompat.myUserHandle(); 156ed13187a745866483139e2878037e1f8427ce567Kenny Guy 157ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (Intent.ACTION_PACKAGE_CHANGED.equals(action) 158ed13187a745866483139e2878037e1f8427ce567Kenny Guy || Intent.ACTION_PACKAGE_REMOVED.equals(action) 159ed13187a745866483139e2878037e1f8427ce567Kenny Guy || Intent.ACTION_PACKAGE_ADDED.equals(action)) { 160ed13187a745866483139e2878037e1f8427ce567Kenny Guy final String packageName = intent.getData().getSchemeSpecificPart(); 161ed13187a745866483139e2878037e1f8427ce567Kenny Guy final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 162ed13187a745866483139e2878037e1f8427ce567Kenny Guy 163ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (packageName == null || packageName.length() == 0) { 164ed13187a745866483139e2878037e1f8427ce567Kenny Guy // they sent us a bad intent 165ed13187a745866483139e2878037e1f8427ce567Kenny Guy return; 166ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 167ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { 168c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy for (OnAppsChangedCallbackCompat callback : getCallbacks()) { 169c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy callback.onPackageChanged(packageName, user); 170ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 171ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 172ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!replacing) { 173c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy for (OnAppsChangedCallbackCompat callback : getCallbacks()) { 174c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy callback.onPackageRemoved(packageName, user); 175ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 176ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 177ed13187a745866483139e2878037e1f8427ce567Kenny Guy // else, we are replacing the package, so a PACKAGE_ADDED will be sent 178ed13187a745866483139e2878037e1f8427ce567Kenny Guy // later, we will update the package at this time 179ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 180ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!replacing) { 181c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy for (OnAppsChangedCallbackCompat callback : getCallbacks()) { 182c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy callback.onPackageAdded(packageName, user); 183ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 184ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 185c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy for (OnAppsChangedCallbackCompat callback : getCallbacks()) { 186c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy callback.onPackageChanged(packageName, user); 187ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 188ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 189ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 190ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 191481c1fb796ea00d725b079a98cd6958247794a83Sunny Goyal // EXTRA_REPLACING is available Kitkat onwards. For lower devices, it is broadcasted 192481c1fb796ea00d725b079a98cd6958247794a83Sunny Goyal // when moving a package or mounting/un-mounting external storage. Assume that 193481c1fb796ea00d725b079a98cd6958247794a83Sunny Goyal // it is a replacing operation. 194481c1fb796ea00d725b079a98cd6958247794a83Sunny Goyal final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, 195481c1fb796ea00d725b079a98cd6958247794a83Sunny Goyal Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT); 196ed13187a745866483139e2878037e1f8427ce567Kenny Guy String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 197c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy for (OnAppsChangedCallbackCompat callback : getCallbacks()) { 198c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy callback.onPackagesAvailable(packages, user, replacing); 199ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 200ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 201481c1fb796ea00d725b079a98cd6958247794a83Sunny Goyal final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, 202481c1fb796ea00d725b079a98cd6958247794a83Sunny Goyal Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT); 203ed13187a745866483139e2878037e1f8427ce567Kenny Guy String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 204c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy for (OnAppsChangedCallbackCompat callback : getCallbacks()) { 205c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy callback.onPackagesUnavailable(packages, user, replacing); 206ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 207ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 208ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 209ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 210ed13187a745866483139e2878037e1f8427ce567Kenny Guy} 211