PackageManagerServiceUtils.java revision 90e269917e1d8f9fadb12c3528b8c360b2271e82
15b539461dcc159bd89297443780d635ccc5e3564John Hoford/* 25b539461dcc159bd89297443780d635ccc5e3564John Hoford * Copyright (C) 2016 The Android Open Source Project 35b539461dcc159bd89297443780d635ccc5e3564John Hoford * 45b539461dcc159bd89297443780d635ccc5e3564John Hoford * Licensed under the Apache License, Version 2.0 (the "License"); 55b539461dcc159bd89297443780d635ccc5e3564John Hoford * you may not use this file except in compliance with the License. 65b539461dcc159bd89297443780d635ccc5e3564John Hoford * You may obtain a copy of the License at 75b539461dcc159bd89297443780d635ccc5e3564John Hoford * 85b539461dcc159bd89297443780d635ccc5e3564John Hoford * http://www.apache.org/licenses/LICENSE-2.0 95b539461dcc159bd89297443780d635ccc5e3564John Hoford * 105b539461dcc159bd89297443780d635ccc5e3564John Hoford * Unless required by applicable law or agreed to in writing, software 115b539461dcc159bd89297443780d635ccc5e3564John Hoford * distributed under the License is distributed on an "AS IS" BASIS, 125b539461dcc159bd89297443780d635ccc5e3564John Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135b539461dcc159bd89297443780d635ccc5e3564John Hoford * See the License for the specific language governing permissions and 145b539461dcc159bd89297443780d635ccc5e3564John Hoford * limitations under the License. 155b539461dcc159bd89297443780d635ccc5e3564John Hoford */ 165b539461dcc159bd89297443780d635ccc5e3564John Hoford 175b539461dcc159bd89297443780d635ccc5e3564John Hofordpackage com.android.server.pm; 185b539461dcc159bd89297443780d635ccc5e3564John Hoford 195b539461dcc159bd89297443780d635ccc5e3564John Hofordimport static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT; 205b539461dcc159bd89297443780d635ccc5e3564John Hofordimport static com.android.server.pm.PackageManagerService.TAG; 215b539461dcc159bd89297443780d635ccc5e3564John Hoford 225b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.app.AppGlobals; 235b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.content.Intent; 245b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.content.pm.PackageParser; 255b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.content.pm.ResolveInfo; 265b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.os.RemoteException; 275b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.os.UserHandle; 285b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.util.ArraySet; 295b539461dcc159bd89297443780d635ccc5e3564John Hofordimport android.util.Log; 305b539461dcc159bd89297443780d635ccc5e3564John Hoford 315b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.ArrayList; 325b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Collection; 335b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Date; 345b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.HashSet; 355b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Iterator; 365b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.LinkedList; 375b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.List; 385b539461dcc159bd89297443780d635ccc5e3564John Hofordimport java.util.Set; 395b539461dcc159bd89297443780d635ccc5e3564John Hoford 405b539461dcc159bd89297443780d635ccc5e3564John Hoford/** 415b539461dcc159bd89297443780d635ccc5e3564John Hoford * Class containing helper methods for the PackageManagerService. 425b539461dcc159bd89297443780d635ccc5e3564John Hoford * 435b539461dcc159bd89297443780d635ccc5e3564John Hoford * {@hide} 445b539461dcc159bd89297443780d635ccc5e3564John Hoford */ 455b539461dcc159bd89297443780d635ccc5e3564John Hofordpublic class PackageManagerServiceUtils { 465b539461dcc159bd89297443780d635ccc5e3564John Hoford private final static long SEVEN_DAYS_IN_MILLISECONDS = 7 * 24 * 60 * 60 * 1000; 475b539461dcc159bd89297443780d635ccc5e3564John Hoford 485b539461dcc159bd89297443780d635ccc5e3564John Hoford private static ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) { 495b539461dcc159bd89297443780d635ccc5e3564John Hoford List<ResolveInfo> ris = null; 505b539461dcc159bd89297443780d635ccc5e3564John Hoford try { 515b539461dcc159bd89297443780d635ccc5e3564John Hoford ris = AppGlobals.getPackageManager().queryIntentReceivers(intent, null, 0, userId) 525b539461dcc159bd89297443780d635ccc5e3564John Hoford .getList(); 535b539461dcc159bd89297443780d635ccc5e3564John Hoford } catch (RemoteException e) { 545b539461dcc159bd89297443780d635ccc5e3564John Hoford } 555b539461dcc159bd89297443780d635ccc5e3564John Hoford ArraySet<String> pkgNames = new ArraySet<String>(); 565b539461dcc159bd89297443780d635ccc5e3564John Hoford if (ris != null) { 575b539461dcc159bd89297443780d635ccc5e3564John Hoford for (ResolveInfo ri : ris) { 585b539461dcc159bd89297443780d635ccc5e3564John Hoford pkgNames.add(ri.activityInfo.packageName); 595b539461dcc159bd89297443780d635ccc5e3564John Hoford } 605b539461dcc159bd89297443780d635ccc5e3564John Hoford } 615b539461dcc159bd89297443780d635ccc5e3564John Hoford return pkgNames; 625b539461dcc159bd89297443780d635ccc5e3564John Hoford } 635b539461dcc159bd89297443780d635ccc5e3564John Hoford 645b539461dcc159bd89297443780d635ccc5e3564John Hoford private static void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs, 655b539461dcc159bd89297443780d635ccc5e3564John Hoford long dexOptLRUThresholdInMills) { 665b539461dcc159bd89297443780d635ccc5e3564John Hoford // Filter out packages that aren't recently used. 675b539461dcc159bd89297443780d635ccc5e3564John Hoford int total = pkgs.size(); 685b539461dcc159bd89297443780d635ccc5e3564John Hoford int skipped = 0; 695b539461dcc159bd89297443780d635ccc5e3564John Hoford long now = System.currentTimeMillis(); 705b539461dcc159bd89297443780d635ccc5e3564John Hoford for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 715b539461dcc159bd89297443780d635ccc5e3564John Hoford PackageParser.Package pkg = i.next(); 725b539461dcc159bd89297443780d635ccc5e3564John Hoford long then = pkg.getLatestForegroundPackageUseTimeInMills(); 735b539461dcc159bd89297443780d635ccc5e3564John Hoford if (then + dexOptLRUThresholdInMills < now) { 745b539461dcc159bd89297443780d635ccc5e3564John Hoford if (DEBUG_DEXOPT) { 755b539461dcc159bd89297443780d635ccc5e3564John Hoford Log.i(TAG, "Skipping dexopt of " + pkg.packageName + 765b539461dcc159bd89297443780d635ccc5e3564John Hoford " last used in foreground: " + 775b539461dcc159bd89297443780d635ccc5e3564John Hoford ((then == 0) ? "never" : new Date(then))); 785b539461dcc159bd89297443780d635ccc5e3564John Hoford } 795b539461dcc159bd89297443780d635ccc5e3564John Hoford i.remove(); 805b539461dcc159bd89297443780d635ccc5e3564John Hoford skipped++; 815b539461dcc159bd89297443780d635ccc5e3564John Hoford } 825b539461dcc159bd89297443780d635ccc5e3564John Hoford } 835b539461dcc159bd89297443780d635ccc5e3564John Hoford if (DEBUG_DEXOPT) { 845b539461dcc159bd89297443780d635ccc5e3564John Hoford Log.i(TAG, "Skipped dexopt " + skipped + " of " + total); 855b539461dcc159bd89297443780d635ccc5e3564John Hoford } 865b539461dcc159bd89297443780d635ccc5e3564John Hoford } 875b539461dcc159bd89297443780d635ccc5e3564John Hoford 885b539461dcc159bd89297443780d635ccc5e3564John Hoford // Sort apps by importance for dexopt ordering. Important apps are given 895b539461dcc159bd89297443780d635ccc5e3564John Hoford // more priority in case the device runs out of space. 905b539461dcc159bd89297443780d635ccc5e3564John Hoford public static List<PackageParser.Package> getPackagesForDexopt( 915b539461dcc159bd89297443780d635ccc5e3564John Hoford Collection<PackageParser.Package> packages, 925b539461dcc159bd89297443780d635ccc5e3564John Hoford PackageManagerService packageManagerService) { 935b539461dcc159bd89297443780d635ccc5e3564John Hoford ArrayList<PackageParser.Package> remainingPkgs = new ArrayList<>(packages); 945b539461dcc159bd89297443780d635ccc5e3564John Hoford LinkedList<PackageParser.Package> result = new LinkedList<>(); 955b539461dcc159bd89297443780d635ccc5e3564John Hoford 965b539461dcc159bd89297443780d635ccc5e3564John Hoford // Give priority to core apps. 975b539461dcc159bd89297443780d635ccc5e3564John Hoford for (PackageParser.Package pkg : remainingPkgs) { 985b539461dcc159bd89297443780d635ccc5e3564John Hoford if (pkg.coreApp) { 995b539461dcc159bd89297443780d635ccc5e3564John Hoford if (DEBUG_DEXOPT) { 1005b539461dcc159bd89297443780d635ccc5e3564John Hoford Log.i(TAG, "Adding core app " + result.size() + ": " + pkg.packageName); 1015b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1025b539461dcc159bd89297443780d635ccc5e3564John Hoford result.add(pkg); 1035b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1045b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1055b539461dcc159bd89297443780d635ccc5e3564John Hoford remainingPkgs.removeAll(result); 1065b539461dcc159bd89297443780d635ccc5e3564John Hoford 1075b539461dcc159bd89297443780d635ccc5e3564John Hoford // Give priority to system apps that listen for pre boot complete. 1085b539461dcc159bd89297443780d635ccc5e3564John Hoford Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 1095b539461dcc159bd89297443780d635ccc5e3564John Hoford ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM); 1105b539461dcc159bd89297443780d635ccc5e3564John Hoford for (PackageParser.Package pkg : remainingPkgs) { 1115b539461dcc159bd89297443780d635ccc5e3564John Hoford if (pkgNames.contains(pkg.packageName)) { 1125b539461dcc159bd89297443780d635ccc5e3564John Hoford if (DEBUG_DEXOPT) { 1135b539461dcc159bd89297443780d635ccc5e3564John Hoford Log.i(TAG, "Adding pre boot system app " + result.size() + ": " + 1145b539461dcc159bd89297443780d635ccc5e3564John Hoford pkg.packageName); 1155b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1165b539461dcc159bd89297443780d635ccc5e3564John Hoford result.add(pkg); 1175b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1185b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1195b539461dcc159bd89297443780d635ccc5e3564John Hoford remainingPkgs.removeAll(result); 1205b539461dcc159bd89297443780d635ccc5e3564John Hoford 1215b539461dcc159bd89297443780d635ccc5e3564John Hoford // Give priority to apps used by other apps. 1225b539461dcc159bd89297443780d635ccc5e3564John Hoford for (PackageParser.Package pkg : remainingPkgs) { 1235b539461dcc159bd89297443780d635ccc5e3564John Hoford if (PackageDexOptimizer.isUsedByOtherApps(pkg)) { 1245b539461dcc159bd89297443780d635ccc5e3564John Hoford if (DEBUG_DEXOPT) { 1255b539461dcc159bd89297443780d635ccc5e3564John Hoford Log.i(TAG, "Adding app used by other apps " + result.size() + ": " + 1265b539461dcc159bd89297443780d635ccc5e3564John Hoford pkg.packageName); 1275b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1285b539461dcc159bd89297443780d635ccc5e3564John Hoford result.add(pkg); 1295b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1305b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1315b539461dcc159bd89297443780d635ccc5e3564John Hoford remainingPkgs.removeAll(result); 1325b539461dcc159bd89297443780d635ccc5e3564John Hoford 1335b539461dcc159bd89297443780d635ccc5e3564John Hoford // Filter out packages that aren't recently used, add all remaining apps. 1345b539461dcc159bd89297443780d635ccc5e3564John Hoford // TODO: add a property to control this? 1355b539461dcc159bd89297443780d635ccc5e3564John Hoford if (packageManagerService.isHistoricalPackageUsageAvailable()) { 1365b539461dcc159bd89297443780d635ccc5e3564John Hoford filterRecentlyUsedApps(remainingPkgs, SEVEN_DAYS_IN_MILLISECONDS); 1375b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1385b539461dcc159bd89297443780d635ccc5e3564John Hoford result.addAll(remainingPkgs); 1395b539461dcc159bd89297443780d635ccc5e3564John Hoford 1405b539461dcc159bd89297443780d635ccc5e3564John Hoford // Now go ahead and also add the libraries required for these packages. 1415b539461dcc159bd89297443780d635ccc5e3564John Hoford // TODO: Think about interleaving things. 1425b539461dcc159bd89297443780d635ccc5e3564John Hoford Set<PackageParser.Package> dependencies = new HashSet<>(); 1435b539461dcc159bd89297443780d635ccc5e3564John Hoford for (PackageParser.Package p : result) { 1445b539461dcc159bd89297443780d635ccc5e3564John Hoford dependencies.addAll(packageManagerService.findSharedNonSystemLibraries(p)); 1455b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1465b539461dcc159bd89297443780d635ccc5e3564John Hoford if (!dependencies.isEmpty()) { 1475b539461dcc159bd89297443780d635ccc5e3564John Hoford // We might have packages already in `result` that are dependencies 1485b539461dcc159bd89297443780d635ccc5e3564John Hoford // of other packages. Make sure we don't add those to the list twice. 1495b539461dcc159bd89297443780d635ccc5e3564John Hoford dependencies.removeAll(result); 1505b539461dcc159bd89297443780d635ccc5e3564John Hoford } 1515b539461dcc159bd89297443780d635ccc5e3564John Hoford result.addAll(dependencies); 1525b539461dcc159bd89297443780d635ccc5e3564John Hoford 153 if (DEBUG_DEXOPT) { 154 StringBuilder sb = new StringBuilder(); 155 for (PackageParser.Package pkg : result) { 156 if (sb.length() > 0) { 157 sb.append(", "); 158 } 159 sb.append(pkg.packageName); 160 } 161 Log.i(TAG, "Packages to be dexopted: " + sb.toString()); 162 } 163 164 return result; 165 } 166}