2 * Copyright (C) 2006 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.server.pm;
19 import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
20 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
26 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
27 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
28 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
29 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
30 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
31 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
32 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
33 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
34 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
35 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
36 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
37 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
38 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
39 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
44 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
45 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
46 import static android.content.pm.PackageParser.isApkFile;
47 import static android.os.Process.PACKAGE_INFO_GID;
48 import static android.os.Process.SYSTEM_UID;
49 import static android.system.OsConstants.O_CREAT;
50 import static android.system.OsConstants.O_RDWR;
51 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
52 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
53 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
54 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
55 import static com.android.internal.util.ArrayUtils.appendInt;
56 import static com.android.internal.util.ArrayUtils.removeInt;
58 import android.util.ArrayMap;
60 import com.android.internal.R;
61 import com.android.internal.app.IMediaContainerService;
62 import com.android.internal.app.ResolverActivity;
63 import com.android.internal.content.NativeLibraryHelper;
64 import com.android.internal.content.PackageHelper;
65 import com.android.internal.os.IParcelFileDescriptorFactory;
66 import com.android.internal.util.ArrayUtils;
67 import com.android.internal.util.FastPrintWriter;
68 import com.android.internal.util.FastXmlSerializer;
69 import com.android.internal.util.IndentingPrintWriter;
70 import com.android.server.EventLogTags;
71 import com.android.server.IntentResolver;
72 import com.android.server.LocalServices;
73 import com.android.server.ServiceThread;
74 import com.android.server.SystemConfig;
75 import com.android.server.Watchdog;
76 import com.android.server.pm.Settings.DatabaseVersion;
77 import com.android.server.storage.DeviceStorageMonitorInternal;
79 import org.xmlpull.v1.XmlSerializer;
81 import android.app.ActivityManager;
82 import android.app.ActivityManagerNative;
83 import android.app.AppGlobals;
84 import android.app.IActivityManager;
85 import android.app.admin.IDevicePolicyManager;
86 import android.app.backup.IBackupManager;
87 import android.content.BroadcastReceiver;
88 import android.content.ComponentName;
89 import android.content.Context;
90 import android.content.IIntentReceiver;
91 import android.content.Intent;
92 import android.content.IntentFilter;
93 import android.content.IntentSender;
94 import android.content.IntentSender.SendIntentException;
95 import android.content.ServiceConnection;
96 import android.content.pm.ActivityInfo;
97 import android.content.pm.ApplicationInfo;
98 import android.content.pm.FeatureInfo;
99 import android.content.pm.IPackageDataObserver;
100 import android.content.pm.IPackageDeleteObserver;
101 import android.content.pm.IPackageDeleteObserver2;
102 import android.content.pm.IPackageInstallObserver2;
103 import android.content.pm.IPackageInstaller;
104 import android.content.pm.IPackageManager;
105 import android.content.pm.IPackageMoveObserver;
106 import android.content.pm.IPackageStatsObserver;
107 import android.content.pm.InstrumentationInfo;
108 import android.content.pm.KeySet;
109 import android.content.pm.ManifestDigest;
110 import android.content.pm.PackageCleanItem;
111 import android.content.pm.PackageInfo;
112 import android.content.pm.PackageInfoLite;
113 import android.content.pm.PackageInstaller;
114 import android.content.pm.PackageManager;
115 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
116 import android.content.pm.PackageParser.ActivityIntentInfo;
117 import android.content.pm.PackageParser.PackageLite;
118 import android.content.pm.PackageParser.PackageParserException;
119 import android.content.pm.PackageParser;
120 import android.content.pm.PackageStats;
121 import android.content.pm.PackageUserState;
122 import android.content.pm.ParceledListSlice;
123 import android.content.pm.PermissionGroupInfo;
124 import android.content.pm.PermissionInfo;
125 import android.content.pm.ProviderInfo;
126 import android.content.pm.ResolveInfo;
127 import android.content.pm.ServiceInfo;
128 import android.content.pm.Signature;
129 import android.content.pm.UserInfo;
130 import android.content.pm.VerificationParams;
131 import android.content.pm.VerifierDeviceIdentity;
132 import android.content.pm.VerifierInfo;
133 import android.content.res.Resources;
134 import android.hardware.display.DisplayManager;
135 import android.net.Uri;
136 import android.os.Binder;
137 import android.os.Build;
138 import android.os.Bundle;
139 import android.os.Environment;
140 import android.os.Environment.UserEnvironment;
141 import android.os.storage.StorageManager;
142 import android.os.Debug;
143 import android.os.FileUtils;
144 import android.os.Handler;
145 import android.os.IBinder;
146 import android.os.Looper;
147 import android.os.Message;
148 import android.os.Parcel;
149 import android.os.ParcelFileDescriptor;
150 import android.os.Process;
151 import android.os.RemoteException;
152 import android.os.SELinux;
153 import android.os.ServiceManager;
154 import android.os.SystemClock;
155 import android.os.SystemProperties;
156 import android.os.UserHandle;
157 import android.os.UserManager;
158 import android.security.KeyStore;
159 import android.security.SystemKeyStore;
160 import android.system.ErrnoException;
161 import android.system.Os;
162 import android.system.StructStat;
163 import android.text.TextUtils;
164 import android.util.ArraySet;
165 import android.util.AtomicFile;
166 import android.util.DisplayMetrics;
167 import android.util.EventLog;
168 import android.util.ExceptionUtils;
169 import android.util.Log;
170 import android.util.LogPrinter;
171 import android.util.PrintStreamPrinter;
172 import android.util.Slog;
173 import android.util.SparseArray;
174 import android.util.SparseBooleanArray;
175 import android.view.Display;
177 import java.io.BufferedInputStream;
178 import java.io.BufferedOutputStream;
179 import java.io.BufferedReader;
181 import java.io.FileDescriptor;
182 import java.io.FileInputStream;
183 import java.io.FileNotFoundException;
184 import java.io.FileOutputStream;
185 import java.io.FileReader;
186 import java.io.FilenameFilter;
187 import java.io.IOException;
188 import java.io.InputStream;
189 import java.io.PrintWriter;
190 import java.nio.charset.StandardCharsets;
191 import java.security.NoSuchAlgorithmException;
192 import java.security.PublicKey;
193 import java.security.cert.CertificateEncodingException;
194 import java.security.cert.CertificateException;
195 import java.text.SimpleDateFormat;
196 import java.util.ArrayList;
197 import java.util.Arrays;
198 import java.util.Collection;
199 import java.util.Collections;
200 import java.util.Comparator;
201 import java.util.Date;
202 import java.util.HashMap;
203 import java.util.HashSet;
204 import java.util.Iterator;
205 import java.util.List;
206 import java.util.Map;
207 import java.util.Objects;
208 import java.util.Set;
209 import java.util.concurrent.atomic.AtomicBoolean;
210 import java.util.concurrent.atomic.AtomicLong;
212 import dalvik.system.DexFile;
213 import dalvik.system.StaleDexCacheError;
214 import dalvik.system.VMRuntime;
216 import libcore.io.IoUtils;
217 import libcore.util.EmptyArray;
220 * Keep track of all those .apks everywhere.
222 * This is very central to the platform's security; please run the unit
223 * tests whenever making modifications here:
225 mmm frameworks/base/tests/AndroidTests
226 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
227 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
231 public class PackageManagerService extends IPackageManager.Stub {
232 static final String TAG = "PackageManager";
233 static final boolean DEBUG_SETTINGS = false;
234 static final boolean DEBUG_PREFERRED = false;
235 static final boolean DEBUG_UPGRADE = false;
236 private static final boolean DEBUG_INSTALL = false;
237 private static final boolean DEBUG_REMOVE = false;
238 private static final boolean DEBUG_BROADCASTS = false;
239 private static final boolean DEBUG_SHOW_INFO = false;
240 private static final boolean DEBUG_PACKAGE_INFO = false;
241 private static final boolean DEBUG_INTENT_MATCHING = false;
242 private static final boolean DEBUG_PACKAGE_SCANNING = false;
243 private static final boolean DEBUG_VERIFY = false;
244 private static final boolean DEBUG_DEXOPT = false;
245 private static final boolean DEBUG_ABI_SELECTION = false;
247 private static final int RADIO_UID = Process.PHONE_UID;
248 private static final int LOG_UID = Process.LOG_UID;
249 private static final int NFC_UID = Process.NFC_UID;
250 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
251 private static final int SHELL_UID = Process.SHELL_UID;
253 // Cap the size of permission trees that 3rd party apps can define
254 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text
256 // Suffix used during package installation when copying/moving
257 // package apks to install directory.
258 private static final String INSTALL_PACKAGE_SUFFIX = "-";
260 static final int SCAN_NO_DEX = 1<<1;
261 static final int SCAN_FORCE_DEX = 1<<2;
262 static final int SCAN_UPDATE_SIGNATURE = 1<<3;
263 static final int SCAN_NEW_INSTALL = 1<<4;
264 static final int SCAN_NO_PATHS = 1<<5;
265 static final int SCAN_UPDATE_TIME = 1<<6;
266 static final int SCAN_DEFER_DEX = 1<<7;
267 static final int SCAN_BOOTING = 1<<8;
268 static final int SCAN_TRUSTED_OVERLAY = 1<<9;
269 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
270 static final int SCAN_REPLACING = 1<<11;
272 static final int REMOVE_CHATTY = 1<<16;
275 * Timeout (in milliseconds) after which the watchdog should declare that
276 * our handler thread is wedged. The usual default for such things is one
277 * minute but we sometimes do very lengthy I/O operations on this thread,
278 * such as installing multi-gigabyte applications, so ours needs to be longer.
280 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
283 * Whether verification is enabled by default.
285 private static final boolean DEFAULT_VERIFY_ENABLE = true;
288 * The default maximum time to wait for the verification agent to return in
291 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
294 * The default response for package verification timeout.
296 * This can be either PackageManager.VERIFICATION_ALLOW or
297 * PackageManager.VERIFICATION_REJECT.
299 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
301 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
303 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
304 DEFAULT_CONTAINER_PACKAGE,
305 "com.android.defcontainer.DefaultContainerService");
307 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
309 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
311 private static String sPreferredInstructionSet;
313 final ServiceThread mHandlerThread;
315 private static final String IDMAP_PREFIX = "/data/resource-cache/";
316 private static final String IDMAP_SUFFIX = "@idmap";
318 final PackageHandler mHandler;
321 * Messages for {@link #mHandler} that need to wait for system ready before
324 private ArrayList<Message> mPostSystemReadyMessages;
326 final int mSdkVersion = Build.VERSION.SDK_INT;
328 final Context mContext;
329 final boolean mFactoryTest;
330 final boolean mOnlyCore;
331 final boolean mLazyDexOpt;
332 final DisplayMetrics mMetrics;
333 final int mDefParseFlags;
334 final String[] mSeparateProcesses;
335 final boolean mIsUpgrade;
337 // This is where all application persistent data goes.
338 final File mAppDataDir;
340 // This is where all application persistent data goes for secondary users.
341 final File mUserAppDataDir;
343 /** The location for ASEC container files on internal storage. */
344 final String mAsecInternalPath;
346 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
347 // LOCK HELD. Can be called with mInstallLock held.
348 final Installer mInstaller;
350 /** Directory where installed third-party apps stored */
351 final File mAppInstallDir;
354 * Directory to which applications installed internally have their
355 * 32 bit native libraries copied.
357 private File mAppLib32InstallDir;
359 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
361 final File mDrmAppPrivateInstallDir;
363 // ----------------------------------------------------------------
365 // Lock for state used when installing and doing other long running
366 // operations. Methods that must be called with this lock held have
368 final Object mInstallLock = new Object();
370 // ----------------------------------------------------------------
372 // Keys are String (package name), values are Package. This also serves
373 // as the lock for the global state. Methods that must be called with
374 // this lock held have the prefix "LP".
375 final HashMap<String, PackageParser.Package> mPackages =
376 new HashMap<String, PackageParser.Package>();
378 // Tracks available target package names -> overlay package paths.
379 final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays =
380 new HashMap<String, HashMap<String, PackageParser.Package>>();
382 final Settings mSettings;
383 boolean mRestoredSettings;
385 // System configuration read by SystemConfig.
386 final int[] mGlobalGids;
387 final SparseArray<HashSet<String>> mSystemPermissions;
388 final HashMap<String, FeatureInfo> mAvailableFeatures;
390 // If mac_permissions.xml was found for seinfo labeling.
391 boolean mFoundPolicyFile;
393 // If a recursive restorecon of /data/data/<pkg> is needed.
394 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
396 public static final class SharedLibraryEntry {
397 public final String path;
398 public final String apk;
400 SharedLibraryEntry(String _path, String _apk) {
406 // Currently known shared libraries.
407 final HashMap<String, SharedLibraryEntry> mSharedLibraries =
408 new HashMap<String, SharedLibraryEntry>();
410 // All available activities, for your resolving pleasure.
411 final ActivityIntentResolver mActivities =
412 new ActivityIntentResolver();
414 // All available receivers, for your resolving pleasure.
415 final ActivityIntentResolver mReceivers =
416 new ActivityIntentResolver();
418 // All available services, for your resolving pleasure.
419 final ServiceIntentResolver mServices = new ServiceIntentResolver();
421 // All available providers, for your resolving pleasure.
422 final ProviderIntentResolver mProviders = new ProviderIntentResolver();
424 // Mapping from provider base names (first directory in content URI codePath)
425 // to the provider information.
426 final HashMap<String, PackageParser.Provider> mProvidersByAuthority =
427 new HashMap<String, PackageParser.Provider>();
429 // Mapping from instrumentation class names to info about them.
430 final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
431 new HashMap<ComponentName, PackageParser.Instrumentation>();
433 // Mapping from permission names to info about them.
434 final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
435 new HashMap<String, PackageParser.PermissionGroup>();
437 // Packages whose data we have transfered into another package, thus
438 // should no longer exist.
439 final HashSet<String> mTransferedPackages = new HashSet<String>();
441 // Broadcast actions that are only available to the system.
442 final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
444 /** List of packages waiting for verification. */
445 final SparseArray<PackageVerificationState> mPendingVerification
446 = new SparseArray<PackageVerificationState>();
448 /** Set of packages associated with each app op permission. */
449 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
451 final PackageInstallerService mInstallerService;
453 HashSet<PackageParser.Package> mDeferredDexOpt = null;
455 // Cache of users who need badging.
456 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
458 /** Token for keys in mPendingVerification. */
459 private int mPendingVerificationToken = 0;
461 volatile boolean mSystemReady;
462 volatile boolean mSafeMode;
463 volatile boolean mHasSystemUidErrors;
465 ApplicationInfo mAndroidApplication;
466 final ActivityInfo mResolveActivity = new ActivityInfo();
467 final ResolveInfo mResolveInfo = new ResolveInfo();
468 ComponentName mResolveComponentName;
469 PackageParser.Package mPlatformPackage;
470 ComponentName mCustomResolverComponentName;
472 boolean mResolverReplaced = false;
474 // Set of pending broadcasts for aggregating enable/disable of components.
475 static class PendingPackageBroadcasts {
476 // for each user id, a map of <package name -> components within that package>
477 final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
479 public PendingPackageBroadcasts() {
480 mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2);
483 public ArrayList<String> get(int userId, String packageName) {
484 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
485 return packages.get(packageName);
488 public void put(int userId, String packageName, ArrayList<String> components) {
489 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
490 packages.put(packageName, components);
493 public void remove(int userId, String packageName) {
494 HashMap<String, ArrayList<String>> packages = mUidMap.get(userId);
495 if (packages != null) {
496 packages.remove(packageName);
500 public void remove(int userId) {
501 mUidMap.remove(userId);
504 public int userIdCount() {
505 return mUidMap.size();
508 public int userIdAt(int n) {
509 return mUidMap.keyAt(n);
512 public HashMap<String, ArrayList<String>> packagesForUserId(int userId) {
513 return mUidMap.get(userId);
517 // total number of pending broadcast entries across all userIds
519 for (int i = 0; i< mUidMap.size(); i++) {
520 num += mUidMap.valueAt(i).size();
525 public void clear() {
529 private HashMap<String, ArrayList<String>> getOrAllocate(int userId) {
530 HashMap<String, ArrayList<String>> map = mUidMap.get(userId);
532 map = new HashMap<String, ArrayList<String>>();
533 mUidMap.put(userId, map);
538 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
540 // Service Connection to remote media container service to copy
541 // package uri's from external media onto secure containers
542 // or internal storage.
543 private IMediaContainerService mContainerService = null;
545 static final int SEND_PENDING_BROADCAST = 1;
546 static final int MCS_BOUND = 3;
547 static final int END_COPY = 4;
548 static final int INIT_COPY = 5;
549 static final int MCS_UNBIND = 6;
550 static final int START_CLEANING_PACKAGE = 7;
551 static final int FIND_INSTALL_LOC = 8;
552 static final int POST_INSTALL = 9;
553 static final int MCS_RECONNECT = 10;
554 static final int MCS_GIVE_UP = 11;
555 static final int UPDATED_MEDIA_STATUS = 12;
556 static final int WRITE_SETTINGS = 13;
557 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
558 static final int PACKAGE_VERIFIED = 15;
559 static final int CHECK_PENDING_VERIFICATION = 16;
561 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
563 // Delay time in millisecs
564 static final int BROADCAST_DELAY = 10 * 1000;
566 static UserManagerService sUserManager;
568 // Stores a list of users whose package restrictions file needs to be updated
569 private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
571 final private DefaultContainerConnection mDefContainerConn =
572 new DefaultContainerConnection();
573 class DefaultContainerConnection implements ServiceConnection {
574 public void onServiceConnected(ComponentName name, IBinder service) {
575 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
576 IMediaContainerService imcs =
577 IMediaContainerService.Stub.asInterface(service);
578 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
581 public void onServiceDisconnected(ComponentName name) {
582 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
586 // Recordkeeping of restore-after-install operations that are currently in flight
587 // between the Package Manager and the Backup Manager
588 class PostInstallData {
589 public InstallArgs args;
590 public PackageInstalledInfo res;
592 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
597 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
598 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
600 private final String mRequiredVerifierPackage;
602 private final PackageUsage mPackageUsage = new PackageUsage();
604 private class PackageUsage {
605 private static final int WRITE_INTERVAL
606 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
608 private final Object mFileLock = new Object();
609 private final AtomicLong mLastWritten = new AtomicLong(0);
610 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
612 private boolean mIsHistoricalPackageUsageAvailable = true;
614 boolean isHistoricalPackageUsageAvailable() {
615 return mIsHistoricalPackageUsageAvailable;
618 void write(boolean force) {
623 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
627 if (mBackgroundWriteRunning.compareAndSet(false, true)) {
628 new Thread("PackageUsage_DiskWriter") {
634 mBackgroundWriteRunning.set(false);
641 private void writeInternal() {
642 synchronized (mPackages) {
643 synchronized (mFileLock) {
644 AtomicFile file = getFile();
645 FileOutputStream f = null;
647 f = file.startWrite();
648 BufferedOutputStream out = new BufferedOutputStream(f);
649 FileUtils.setPermissions(file.getBaseFile().getPath(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
650 StringBuilder sb = new StringBuilder();
651 for (PackageParser.Package pkg : mPackages.values()) {
652 if (pkg.mLastPackageUsageTimeInMills == 0) {
656 sb.append(pkg.packageName);
658 sb.append((long)pkg.mLastPackageUsageTimeInMills);
660 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
664 } catch (IOException e) {
668 Log.e(TAG, "Failed to write package usage times", e);
672 mLastWritten.set(SystemClock.elapsedRealtime());
676 synchronized (mFileLock) {
677 AtomicFile file = getFile();
678 BufferedInputStream in = null;
680 in = new BufferedInputStream(file.openRead());
681 StringBuffer sb = new StringBuffer();
683 String packageName = readToken(in, sb, ' ');
684 if (packageName == null) {
687 String timeInMillisString = readToken(in, sb, '\n');
688 if (timeInMillisString == null) {
689 throw new IOException("Failed to find last usage time for package "
692 PackageParser.Package pkg = mPackages.get(packageName);
698 timeInMillis = Long.parseLong(timeInMillisString.toString());
699 } catch (NumberFormatException e) {
700 throw new IOException("Failed to parse " + timeInMillisString
703 pkg.mLastPackageUsageTimeInMills = timeInMillis;
705 } catch (FileNotFoundException expected) {
706 mIsHistoricalPackageUsageAvailable = false;
707 } catch (IOException e) {
708 Log.w(TAG, "Failed to read package usage times", e);
710 IoUtils.closeQuietly(in);
713 mLastWritten.set(SystemClock.elapsedRealtime());
716 private String readToken(InputStream in, StringBuffer sb, char endOfToken)
722 if (sb.length() == 0) {
725 throw new IOException("Unexpected EOF");
727 if (ch == endOfToken) {
728 return sb.toString();
734 private AtomicFile getFile() {
735 File dataDir = Environment.getDataDirectory();
736 File systemDir = new File(dataDir, "system");
737 File fname = new File(systemDir, "package-usage.list");
738 return new AtomicFile(fname);
742 class PackageHandler extends Handler {
743 private boolean mBound = false;
744 final ArrayList<HandlerParams> mPendingInstalls =
745 new ArrayList<HandlerParams>();
747 private boolean connectToService() {
748 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
749 " DefaultContainerService");
750 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
751 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
752 if (mContext.bindServiceAsUser(service, mDefContainerConn,
753 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
754 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
758 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
762 private void disconnectService() {
763 mContainerService = null;
765 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
766 mContext.unbindService(mDefContainerConn);
767 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
770 PackageHandler(Looper looper) {
774 public void handleMessage(Message msg) {
776 doHandleMessage(msg);
778 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
782 void doHandleMessage(Message msg) {
785 HandlerParams params = (HandlerParams) msg.obj;
786 int idx = mPendingInstalls.size();
787 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
788 // If a bind was already initiated we dont really
789 // need to do anything. The pending install
790 // will be processed later on.
792 // If this is the only one pending we might
793 // have to bind to the service again.
794 if (!connectToService()) {
795 Slog.e(TAG, "Failed to bind to media container service");
796 params.serviceError();
799 // Once we bind to the service, the first
800 // pending request will be processed.
801 mPendingInstalls.add(idx, params);
804 mPendingInstalls.add(idx, params);
805 // Already bound to the service. Just make
806 // sure we trigger off processing the first request.
808 mHandler.sendEmptyMessage(MCS_BOUND);
814 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
815 if (msg.obj != null) {
816 mContainerService = (IMediaContainerService) msg.obj;
818 if (mContainerService == null) {
819 // Something seriously wrong. Bail out
820 Slog.e(TAG, "Cannot bind to media container service");
821 for (HandlerParams params : mPendingInstalls) {
822 // Indicate service bind error
823 params.serviceError();
825 mPendingInstalls.clear();
826 } else if (mPendingInstalls.size() > 0) {
827 HandlerParams params = mPendingInstalls.get(0);
828 if (params != null) {
829 if (params.startCopy()) {
830 // We are done... look for more work or to
832 if (DEBUG_SD_INSTALL) Log.i(TAG,
833 "Checking for more work or unbind...");
834 // Delete pending install
835 if (mPendingInstalls.size() > 0) {
836 mPendingInstalls.remove(0);
838 if (mPendingInstalls.size() == 0) {
840 if (DEBUG_SD_INSTALL) Log.i(TAG,
841 "Posting delayed MCS_UNBIND");
842 removeMessages(MCS_UNBIND);
843 Message ubmsg = obtainMessage(MCS_UNBIND);
844 // Unbind after a little delay, to avoid
845 // continual thrashing.
846 sendMessageDelayed(ubmsg, 10000);
849 // There are more pending requests in queue.
850 // Just post MCS_BOUND message to trigger processing
851 // of next pending install.
852 if (DEBUG_SD_INSTALL) Log.i(TAG,
853 "Posting MCS_BOUND for next work");
854 mHandler.sendEmptyMessage(MCS_BOUND);
859 // Should never happen ideally.
860 Slog.w(TAG, "Empty queue");
864 case MCS_RECONNECT: {
865 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
866 if (mPendingInstalls.size() > 0) {
870 if (!connectToService()) {
871 Slog.e(TAG, "Failed to bind to media container service");
872 for (HandlerParams params : mPendingInstalls) {
873 // Indicate service bind error
874 params.serviceError();
876 mPendingInstalls.clear();
882 // If there is no actual work left, then time to unbind.
883 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
885 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
887 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
891 } else if (mPendingInstalls.size() > 0) {
892 // There are more pending requests in queue.
893 // Just post MCS_BOUND message to trigger processing
894 // of next pending install.
895 mHandler.sendEmptyMessage(MCS_BOUND);
901 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
902 mPendingInstalls.remove(0);
905 case SEND_PENDING_BROADCAST: {
907 ArrayList<String> components[];
910 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
911 synchronized (mPackages) {
912 if (mPendingBroadcasts == null) {
915 size = mPendingBroadcasts.size();
917 // Nothing to be done. Just return
920 packages = new String[size];
921 components = new ArrayList[size];
922 uids = new int[size];
923 int i = 0; // filling out the above arrays
925 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
926 int packageUserId = mPendingBroadcasts.userIdAt(n);
927 Iterator<Map.Entry<String, ArrayList<String>>> it
928 = mPendingBroadcasts.packagesForUserId(packageUserId)
929 .entrySet().iterator();
930 while (it.hasNext() && i < size) {
931 Map.Entry<String, ArrayList<String>> ent = it.next();
932 packages[i] = ent.getKey();
933 components[i] = ent.getValue();
934 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
935 uids[i] = (ps != null)
936 ? UserHandle.getUid(packageUserId, ps.appId)
942 mPendingBroadcasts.clear();
945 for (int i = 0; i < size; i++) {
946 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
948 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
951 case START_CLEANING_PACKAGE: {
952 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
953 final String packageName = (String)msg.obj;
954 final int userId = msg.arg1;
955 final boolean andCode = msg.arg2 != 0;
956 synchronized (mPackages) {
957 if (userId == UserHandle.USER_ALL) {
958 int[] users = sUserManager.getUserIds();
959 for (int user : users) {
960 mSettings.addPackageToCleanLPw(
961 new PackageCleanItem(user, packageName, andCode));
964 mSettings.addPackageToCleanLPw(
965 new PackageCleanItem(userId, packageName, andCode));
968 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
969 startCleaningPackages();
972 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
973 PostInstallData data = mRunningInstalls.get(msg.arg1);
974 mRunningInstalls.delete(msg.arg1);
975 boolean deleteOld = false;
978 InstallArgs args = data.args;
979 PackageInstalledInfo res = data.res;
981 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
982 res.removedInfo.sendBroadcast(false, true, false);
983 Bundle extras = new Bundle(1);
984 extras.putInt(Intent.EXTRA_UID, res.uid);
985 // Determine the set of users who are adding this
986 // package for the first time vs. those who are seeing
989 int[] updateUsers = new int[0];
990 if (res.origUsers == null || res.origUsers.length == 0) {
991 firstUsers = res.newUsers;
993 firstUsers = new int[0];
994 for (int i=0; i<res.newUsers.length; i++) {
995 int user = res.newUsers[i];
996 boolean isNew = true;
997 for (int j=0; j<res.origUsers.length; j++) {
998 if (res.origUsers[j] == user) {
1004 int[] newFirst = new int[firstUsers.length+1];
1005 System.arraycopy(firstUsers, 0, newFirst, 0,
1007 newFirst[firstUsers.length] = user;
1008 firstUsers = newFirst;
1010 int[] newUpdate = new int[updateUsers.length+1];
1011 System.arraycopy(updateUsers, 0, newUpdate, 0,
1012 updateUsers.length);
1013 newUpdate[updateUsers.length] = user;
1014 updateUsers = newUpdate;
1018 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1019 res.pkg.applicationInfo.packageName,
1020 extras, null, null, firstUsers);
1021 final boolean update = res.removedInfo.removedPackage != null;
1023 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1025 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1026 res.pkg.applicationInfo.packageName,
1027 extras, null, null, updateUsers);
1029 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1030 res.pkg.applicationInfo.packageName,
1031 extras, null, null, updateUsers);
1032 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1034 res.pkg.applicationInfo.packageName, null, updateUsers);
1036 // treat asec-hosted packages like removable media on upgrade
1037 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
1038 if (DEBUG_INSTALL) {
1039 Slog.i(TAG, "upgrading pkg " + res.pkg
1040 + " is ASEC-hosted -> AVAILABLE");
1042 int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1043 ArrayList<String> pkgList = new ArrayList<String>(1);
1044 pkgList.add(res.pkg.applicationInfo.packageName);
1045 sendResourcesChangedBroadcast(true, true,
1046 pkgList,uidArray, null);
1049 if (res.removedInfo.args != null) {
1050 // Remove the replaced package's older resources safely now
1054 // Log current value of "unknown sources" setting
1055 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1056 getUnknownSourcesSettings());
1058 // Force a gc to clear up things
1059 Runtime.getRuntime().gc();
1060 // We delete after a gc for applications on sdcard.
1062 synchronized (mInstallLock) {
1063 res.removedInfo.args.doPostDeleteLI(true);
1066 if (args.observer != null) {
1068 Bundle extras = extrasForInstallResult(res);
1069 args.observer.onPackageInstalled(res.name, res.returnCode,
1070 res.returnMsg, extras);
1071 } catch (RemoteException e) {
1072 Slog.i(TAG, "Observer no longer exists.");
1076 Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1079 case UPDATED_MEDIA_STATUS: {
1080 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1081 boolean reportStatus = msg.arg1 == 1;
1082 boolean doGc = msg.arg2 == 1;
1083 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1085 // Force a gc to clear up stale containers.
1086 Runtime.getRuntime().gc();
1088 if (msg.obj != null) {
1089 @SuppressWarnings("unchecked")
1090 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1091 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1092 // Unload containers
1093 unloadAllContainers(args);
1097 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1098 PackageHelper.getMountService().finishMediaUpdate();
1099 } catch (RemoteException e) {
1100 Log.e(TAG, "MountService not running?");
1104 case WRITE_SETTINGS: {
1105 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1106 synchronized (mPackages) {
1107 removeMessages(WRITE_SETTINGS);
1108 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1109 mSettings.writeLPr();
1110 mDirtyUsers.clear();
1112 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1114 case WRITE_PACKAGE_RESTRICTIONS: {
1115 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1116 synchronized (mPackages) {
1117 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1118 for (int userId : mDirtyUsers) {
1119 mSettings.writePackageRestrictionsLPr(userId);
1121 mDirtyUsers.clear();
1123 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1125 case CHECK_PENDING_VERIFICATION: {
1126 final int verificationId = msg.arg1;
1127 final PackageVerificationState state = mPendingVerification.get(verificationId);
1129 if ((state != null) && !state.timeoutExtended()) {
1130 final InstallArgs args = state.getInstallArgs();
1131 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1133 Slog.i(TAG, "Verification timed out for " + originUri);
1134 mPendingVerification.remove(verificationId);
1136 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1138 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1139 Slog.i(TAG, "Continuing with installation of " + originUri);
1140 state.setVerifierResponse(Binder.getCallingUid(),
1141 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1142 broadcastPackageVerified(verificationId, originUri,
1143 PackageManager.VERIFICATION_ALLOW,
1144 state.getInstallArgs().getUser());
1146 ret = args.copyApk(mContainerService, true);
1147 } catch (RemoteException e) {
1148 Slog.e(TAG, "Could not contact the ContainerService");
1151 broadcastPackageVerified(verificationId, originUri,
1152 PackageManager.VERIFICATION_REJECT,
1153 state.getInstallArgs().getUser());
1156 processPendingInstall(args, ret);
1157 mHandler.sendEmptyMessage(MCS_UNBIND);
1161 case PACKAGE_VERIFIED: {
1162 final int verificationId = msg.arg1;
1164 final PackageVerificationState state = mPendingVerification.get(verificationId);
1165 if (state == null) {
1166 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1170 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1172 state.setVerifierResponse(response.callerUid, response.code);
1174 if (state.isVerificationComplete()) {
1175 mPendingVerification.remove(verificationId);
1177 final InstallArgs args = state.getInstallArgs();
1178 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1181 if (state.isInstallAllowed()) {
1182 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1183 broadcastPackageVerified(verificationId, originUri,
1184 response.code, state.getInstallArgs().getUser());
1186 ret = args.copyApk(mContainerService, true);
1187 } catch (RemoteException e) {
1188 Slog.e(TAG, "Could not contact the ContainerService");
1191 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1194 processPendingInstall(args, ret);
1196 mHandler.sendEmptyMessage(MCS_UNBIND);
1205 Bundle extrasForInstallResult(PackageInstalledInfo res) {
1206 Bundle extras = null;
1207 switch (res.returnCode) {
1208 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1209 extras = new Bundle();
1210 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1211 res.origPermission);
1212 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1220 void scheduleWriteSettingsLocked() {
1221 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1222 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1226 void scheduleWritePackageRestrictionsLocked(int userId) {
1227 if (!sUserManager.exists(userId)) return;
1228 mDirtyUsers.add(userId);
1229 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1230 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1234 public static final PackageManagerService main(Context context, Installer installer,
1235 boolean factoryTest, boolean onlyCore) {
1236 PackageManagerService m = new PackageManagerService(context, installer,
1237 factoryTest, onlyCore);
1238 ServiceManager.addService("package", m);
1242 static String[] splitString(String str, char sep) {
1245 while ((i=str.indexOf(sep, i)) >= 0) {
1250 String[] res = new String[count];
1254 while ((i=str.indexOf(sep, i)) >= 0) {
1255 res[count] = str.substring(lastI, i);
1260 res[count] = str.substring(lastI, str.length());
1264 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1265 DisplayManager displayManager = (DisplayManager) context.getSystemService(
1266 Context.DISPLAY_SERVICE);
1267 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1270 public PackageManagerService(Context context, Installer installer,
1271 boolean factoryTest, boolean onlyCore) {
1272 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1273 SystemClock.uptimeMillis());
1275 if (mSdkVersion <= 0) {
1276 Slog.w(TAG, "**** ro.build.version.sdk not set!");
1280 mFactoryTest = factoryTest;
1281 mOnlyCore = onlyCore;
1282 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1283 mMetrics = new DisplayMetrics();
1284 mSettings = new Settings(context);
1285 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1286 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1287 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1288 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1289 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1290 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1291 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1292 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1293 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1294 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1295 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1296 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1298 String separateProcesses = SystemProperties.get("debug.separate_processes");
1299 if (separateProcesses != null && separateProcesses.length() > 0) {
1300 if ("*".equals(separateProcesses)) {
1301 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1302 mSeparateProcesses = null;
1303 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1306 mSeparateProcesses = separateProcesses.split(",");
1307 Slog.w(TAG, "Running with debug.separate_processes: "
1308 + separateProcesses);
1312 mSeparateProcesses = null;
1315 mInstaller = installer;
1317 getDefaultDisplayMetrics(context, mMetrics);
1319 SystemConfig systemConfig = SystemConfig.getInstance();
1320 mGlobalGids = systemConfig.getGlobalGids();
1321 mSystemPermissions = systemConfig.getSystemPermissions();
1322 mAvailableFeatures = systemConfig.getAvailableFeatures();
1324 synchronized (mInstallLock) {
1326 synchronized (mPackages) {
1327 mHandlerThread = new ServiceThread(TAG,
1328 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1329 mHandlerThread.start();
1330 mHandler = new PackageHandler(mHandlerThread.getLooper());
1331 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1333 File dataDir = Environment.getDataDirectory();
1334 mAppDataDir = new File(dataDir, "data");
1335 mAppInstallDir = new File(dataDir, "app");
1336 mAppLib32InstallDir = new File(dataDir, "app-lib");
1337 mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1338 mUserAppDataDir = new File(dataDir, "user");
1339 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1341 sUserManager = new UserManagerService(context, this,
1342 mInstallLock, mPackages);
1344 // Propagate permission configuration in to package manager.
1345 ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1346 = systemConfig.getPermissions();
1347 for (int i=0; i<permConfig.size(); i++) {
1348 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1349 BasePermission bp = mSettings.mPermissions.get(perm.name);
1351 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1352 mSettings.mPermissions.put(perm.name, bp);
1354 if (perm.gids != null) {
1355 bp.gids = appendInts(bp.gids, perm.gids);
1359 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1360 for (int i=0; i<libConfig.size(); i++) {
1361 mSharedLibraries.put(libConfig.keyAt(i),
1362 new SharedLibraryEntry(libConfig.valueAt(i), null));
1365 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1367 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1368 mSdkVersion, mOnlyCore);
1370 String customResolverActivity = Resources.getSystem().getString(
1371 R.string.config_customResolverActivity);
1372 if (TextUtils.isEmpty(customResolverActivity)) {
1373 customResolverActivity = null;
1375 mCustomResolverComponentName = ComponentName.unflattenFromString(
1376 customResolverActivity);
1379 long startTime = SystemClock.uptimeMillis();
1381 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1384 // Set flag to monitor and not change apk file paths when
1385 // scanning install directories.
1386 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1388 final HashSet<String> alreadyDexOpted = new HashSet<String>();
1391 * Add everything in the in the boot class path to the
1392 * list of process files because dexopt will have been run
1393 * if necessary during zygote startup.
1395 final String bootClassPath = System.getenv("BOOTCLASSPATH");
1396 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1398 if (bootClassPath != null) {
1399 String[] bootClassPathElements = splitString(bootClassPath, ':');
1400 for (String element : bootClassPathElements) {
1401 alreadyDexOpted.add(element);
1404 Slog.w(TAG, "No BOOTCLASSPATH found!");
1407 if (systemServerClassPath != null) {
1408 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1409 for (String element : systemServerClassPathElements) {
1410 alreadyDexOpted.add(element);
1413 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1416 boolean didDexOptLibraryOrTool = false;
1418 final List<String> allInstructionSets = getAllInstructionSets();
1419 final String[] dexCodeInstructionSets =
1420 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
1423 * Ensure all external libraries have had dexopt run on them.
1425 if (mSharedLibraries.size() > 0) {
1426 // NOTE: For now, we're compiling these system "shared libraries"
1427 // (and framework jars) into all available architectures. It's possible
1428 // to compile them only when we come across an app that uses them (there's
1429 // already logic for that in scanPackageLI) but that adds some complexity.
1430 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1431 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1432 final String lib = libEntry.path;
1438 byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
1439 dexCodeInstructionSet,
1441 if (dexoptRequired != DexFile.UP_TO_DATE) {
1442 alreadyDexOpted.add(lib);
1444 // The list of "shared libraries" we have at this point is
1445 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1446 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1448 mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1450 didDexOptLibraryOrTool = true;
1452 } catch (FileNotFoundException e) {
1453 Slog.w(TAG, "Library not found: " + lib);
1454 } catch (IOException e) {
1455 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1462 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1464 // Gross hack for now: we know this file doesn't contain any
1465 // code, so don't dexopt it to avoid the resulting log spew.
1466 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1468 // Gross hack for now: we know this file is only part of
1469 // the boot class path for art, so don't dexopt it to
1470 // avoid the resulting log spew.
1471 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1474 * And there are a number of commands implemented in Java, which
1475 * we currently need to do the dexopt on so that they can be
1476 * run from a non-root shell.
1478 String[] frameworkFiles = frameworkDir.list();
1479 if (frameworkFiles != null) {
1480 // TODO: We could compile these only for the most preferred ABI. We should
1481 // first double check that the dex files for these commands are not referenced
1482 // by other system apps.
1483 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1484 for (int i=0; i<frameworkFiles.length; i++) {
1485 File libPath = new File(frameworkDir, frameworkFiles[i]);
1486 String path = libPath.getPath();
1487 // Skip the file if we already did it.
1488 if (alreadyDexOpted.contains(path)) {
1491 // Skip the file if it is not a type we want to dexopt.
1492 if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1496 byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
1497 dexCodeInstructionSet,
1499 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1500 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1501 didDexOptLibraryOrTool = true;
1502 } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
1503 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1504 didDexOptLibraryOrTool = true;
1506 } catch (FileNotFoundException e) {
1507 Slog.w(TAG, "Jar not found: " + path);
1508 } catch (IOException e) {
1509 Slog.w(TAG, "Exception reading jar: " + path, e);
1515 // Collect vendor overlay packages.
1516 // (Do this before scanning any apps.)
1517 // For security and version matching reason, only consider
1518 // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1519 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1520 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1521 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
1523 // Find base frameworks (resource packages without code).
1524 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1525 | PackageParser.PARSE_IS_SYSTEM_DIR
1526 | PackageParser.PARSE_IS_PRIVILEGED,
1527 scanFlags | SCAN_NO_DEX, 0);
1529 // Collected privileged system packages.
1530 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1531 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1532 | PackageParser.PARSE_IS_SYSTEM_DIR
1533 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
1535 // Collect ordinary system packages.
1536 final File systemAppDir = new File(Environment.getRootDirectory(), "app");
1537 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1538 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1540 // Collect all vendor packages.
1541 File vendorAppDir = new File("/vendor/app");
1543 vendorAppDir = vendorAppDir.getCanonicalFile();
1544 } catch (IOException e) {
1545 // failed to look up canonical path, continue with original one
1547 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1548 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1550 // Collect all OEM packages.
1551 final File oemAppDir = new File(Environment.getOemDirectory(), "app");
1552 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1553 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1555 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1556 mInstaller.moveFiles();
1558 // Prune any system packages that no longer exist.
1559 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1560 final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
1562 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1563 while (psit.hasNext()) {
1564 PackageSetting ps = psit.next();
1567 * If this is not a system app, it can't be a
1568 * disable system app.
1570 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1575 * If the package is scanned, it's not erased.
1577 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1578 if (scannedPkg != null) {
1580 * If the system app is both scanned and in the
1581 * disabled packages list, then it must have been
1582 * added via OTA. Remove it from the currently
1583 * scanned package so the previously user-installed
1584 * application can be scanned.
1586 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1587 logCriticalInfo(Log.WARN, "Expecting better updated system app for "
1588 + ps.name + "; removing system app. Last known codePath="
1589 + ps.codePathString + ", installStatus=" + ps.installStatus
1590 + ", versionCode=" + ps.versionCode + "; scanned versionCode="
1591 + scannedPkg.mVersionCode);
1592 removePackageLI(ps, true);
1593 expectingBetter.put(ps.name, ps.codePath);
1599 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1601 logCriticalInfo(Log.WARN, "System package " + ps.name
1602 + " no longer exists; wiping its data");
1603 removeDataDirsLI(ps.name);
1605 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1606 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1607 possiblyDeletedUpdatedSystemApps.add(ps.name);
1613 //look for any incomplete package installations
1614 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1616 for(int i = 0; i < deletePkgsList.size(); i++) {
1618 cleanupInstallFailedPackage(deletePkgsList.get(i));
1621 deleteTempPackageFiles();
1623 // Remove any shared userIDs that have no associated packages
1624 mSettings.pruneSharedUsersLPw();
1627 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1628 SystemClock.uptimeMillis());
1629 scanDirLI(mAppInstallDir, 0, scanFlags, 0);
1631 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1635 * Remove disable package settings for any updated system
1636 * apps that were removed via an OTA. If they're not a
1637 * previously-updated app, remove them completely.
1638 * Otherwise, just revoke their system-level permissions.
1640 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1641 PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1642 mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1645 if (deletedPkg == null) {
1646 msg = "Updated system package " + deletedAppName
1647 + " no longer exists; wiping its data";
1648 removeDataDirsLI(deletedAppName);
1650 msg = "Updated system app + " + deletedAppName
1651 + " no longer present; removing system privileges for "
1654 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1656 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1657 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1659 logCriticalInfo(Log.WARN, msg);
1663 * Make sure all system apps that we expected to appear on
1664 * the userdata partition actually showed up. If they never
1665 * appeared, crawl back and revive the system version.
1667 for (int i = 0; i < expectingBetter.size(); i++) {
1668 final String packageName = expectingBetter.keyAt(i);
1669 if (!mPackages.containsKey(packageName)) {
1670 final File scanFile = expectingBetter.valueAt(i);
1672 logCriticalInfo(Log.WARN, "Expected better " + packageName
1673 + " but never showed up; reverting to system");
1675 final int reparseFlags;
1676 if (FileUtils.contains(privilegedAppDir, scanFile)) {
1677 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1678 | PackageParser.PARSE_IS_SYSTEM_DIR
1679 | PackageParser.PARSE_IS_PRIVILEGED;
1680 } else if (FileUtils.contains(systemAppDir, scanFile)) {
1681 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1682 | PackageParser.PARSE_IS_SYSTEM_DIR;
1683 } else if (FileUtils.contains(vendorAppDir, scanFile)) {
1684 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1685 | PackageParser.PARSE_IS_SYSTEM_DIR;
1686 } else if (FileUtils.contains(oemAppDir, scanFile)) {
1687 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1688 | PackageParser.PARSE_IS_SYSTEM_DIR;
1690 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
1694 mSettings.enableSystemPackageLPw(packageName);
1697 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
1698 } catch (PackageManagerException e) {
1699 Slog.e(TAG, "Failed to parse original system package: "
1706 // Now that we know all of the shared libraries, update all clients to have
1707 // the correct library paths.
1708 updateAllSharedLibrariesLPw();
1710 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
1711 // NOTE: We ignore potential failures here during a system scan (like
1712 // the rest of the commands above) because there's precious little we
1713 // can do about it. A settings error is reported, though.
1714 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
1715 false /* force dexopt */, false /* defer dexopt */);
1718 // Now that we know all the packages we are keeping,
1719 // read and update their last usage times.
1720 mPackageUsage.readLP();
1722 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1723 SystemClock.uptimeMillis());
1724 Slog.i(TAG, "Time to scan packages: "
1725 + ((SystemClock.uptimeMillis()-startTime)/1000f)
1728 // If the platform SDK has changed since the last time we booted,
1729 // we need to re-grant app permission to catch any new ones that
1730 // appear. This is really a hack, and means that apps can in some
1731 // cases get permissions that the user didn't initially explicitly
1732 // allow... it would be nice to have some better way to handle
1734 final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1736 if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1737 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1738 + "; regranting permissions for internal storage");
1739 mSettings.mInternalSdkPlatform = mSdkVersion;
1741 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1742 | (regrantPermissions
1743 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1746 // If this is the first boot, and it is a normal boot, then
1747 // we need to initialize the default preferred apps.
1748 if (!mRestoredSettings && !onlyCore) {
1749 mSettings.readDefaultPreferredAppsLPw(this, 0);
1752 // If this is first boot after an OTA, and a normal boot, then
1753 // we need to clear code cache directories.
1754 mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
1755 if (mIsUpgrade && !onlyCore) {
1756 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
1757 for (String pkgName : mSettings.mPackages.keySet()) {
1758 deleteCodeCacheDirsLI(pkgName);
1760 mSettings.mFingerprint = Build.FINGERPRINT;
1763 // All the changes are done during package scanning.
1764 mSettings.updateInternalDatabaseVersion();
1766 // can downgrade to reader
1767 mSettings.writeLPr();
1769 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1770 SystemClock.uptimeMillis());
1773 mRequiredVerifierPackage = getRequiredVerifierLPr();
1774 } // synchronized (mPackages)
1775 } // synchronized (mInstallLock)
1777 mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
1779 // Now after opening every single application zip, make sure they
1780 // are all flushed. Not really needed, but keeps things nice and
1782 Runtime.getRuntime().gc();
1786 public boolean isFirstBoot() {
1787 return !mRestoredSettings;
1791 public boolean isOnlyCoreApps() {
1796 public boolean isUpgrade() {
1800 private String getRequiredVerifierLPr() {
1801 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1802 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1803 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1805 String requiredVerifier = null;
1807 final int N = receivers.size();
1808 for (int i = 0; i < N; i++) {
1809 final ResolveInfo info = receivers.get(i);
1811 if (info.activityInfo == null) {
1815 final String packageName = info.activityInfo.packageName;
1817 final PackageSetting ps = mSettings.mPackages.get(packageName);
1822 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1823 if (!gp.grantedPermissions
1824 .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1828 if (requiredVerifier != null) {
1829 throw new RuntimeException("There can be only one required verifier");
1832 requiredVerifier = packageName;
1835 return requiredVerifier;
1839 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1840 throws RemoteException {
1842 return super.onTransact(code, data, reply, flags);
1843 } catch (RuntimeException e) {
1844 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1845 Slog.wtf(TAG, "Package Manager Crash", e);
1851 void cleanupInstallFailedPackage(PackageSetting ps) {
1852 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
1854 removeDataDirsLI(ps.name);
1855 if (ps.codePath != null) {
1856 if (ps.codePath.isDirectory()) {
1857 FileUtils.deleteContents(ps.codePath);
1859 ps.codePath.delete();
1861 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
1862 if (ps.resourcePath.isDirectory()) {
1863 FileUtils.deleteContents(ps.resourcePath);
1865 ps.resourcePath.delete();
1867 mSettings.removePackageLPw(ps.name);
1870 static int[] appendInts(int[] cur, int[] add) {
1871 if (add == null) return cur;
1872 if (cur == null) return add;
1873 final int N = add.length;
1874 for (int i=0; i<N; i++) {
1875 cur = appendInt(cur, add[i]);
1880 static int[] removeInts(int[] cur, int[] rem) {
1881 if (rem == null) return cur;
1882 if (cur == null) return cur;
1883 final int N = rem.length;
1884 for (int i=0; i<N; i++) {
1885 cur = removeInt(cur, rem[i]);
1890 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1891 if (!sUserManager.exists(userId)) return null;
1892 final PackageSetting ps = (PackageSetting) p.mExtras;
1896 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1897 final PackageUserState state = ps.readUserState(userId);
1898 return PackageParser.generatePackageInfo(p, gp.gids, flags,
1899 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1904 public boolean isPackageAvailable(String packageName, int userId) {
1905 if (!sUserManager.exists(userId)) return false;
1906 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
1907 synchronized (mPackages) {
1908 PackageParser.Package p = mPackages.get(packageName);
1910 final PackageSetting ps = (PackageSetting) p.mExtras;
1912 final PackageUserState state = ps.readUserState(userId);
1913 if (state != null) {
1914 return PackageParser.isAvailable(state);
1923 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1924 if (!sUserManager.exists(userId)) return null;
1925 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
1927 synchronized (mPackages) {
1928 PackageParser.Package p = mPackages.get(packageName);
1929 if (DEBUG_PACKAGE_INFO)
1930 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1932 return generatePackageInfo(p, flags, userId);
1934 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1935 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1942 public String[] currentToCanonicalPackageNames(String[] names) {
1943 String[] out = new String[names.length];
1945 synchronized (mPackages) {
1946 for (int i=names.length-1; i>=0; i--) {
1947 PackageSetting ps = mSettings.mPackages.get(names[i]);
1948 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1955 public String[] canonicalToCurrentPackageNames(String[] names) {
1956 String[] out = new String[names.length];
1958 synchronized (mPackages) {
1959 for (int i=names.length-1; i>=0; i--) {
1960 String cur = mSettings.mRenamedPackages.get(names[i]);
1961 out[i] = cur != null ? cur : names[i];
1968 public int getPackageUid(String packageName, int userId) {
1969 if (!sUserManager.exists(userId)) return -1;
1970 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
1972 synchronized (mPackages) {
1973 PackageParser.Package p = mPackages.get(packageName);
1975 return UserHandle.getUid(userId, p.applicationInfo.uid);
1977 PackageSetting ps = mSettings.mPackages.get(packageName);
1978 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1982 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1987 public int[] getPackageGids(String packageName) {
1989 synchronized (mPackages) {
1990 PackageParser.Package p = mPackages.get(packageName);
1991 if (DEBUG_PACKAGE_INFO)
1992 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1994 final PackageSetting ps = (PackageSetting)p.mExtras;
1995 return ps.getGids();
1998 // stupid thing to indicate an error.
2002 static final PermissionInfo generatePermissionInfo(
2003 BasePermission bp, int flags) {
2004 if (bp.perm != null) {
2005 return PackageParser.generatePermissionInfo(bp.perm, flags);
2007 PermissionInfo pi = new PermissionInfo();
2009 pi.packageName = bp.sourcePackage;
2010 pi.nonLocalizedLabel = bp.name;
2011 pi.protectionLevel = bp.protectionLevel;
2016 public PermissionInfo getPermissionInfo(String name, int flags) {
2018 synchronized (mPackages) {
2019 final BasePermission p = mSettings.mPermissions.get(name);
2021 return generatePermissionInfo(p, flags);
2028 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2030 synchronized (mPackages) {
2031 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2032 for (BasePermission p : mSettings.mPermissions.values()) {
2033 if (group == null) {
2034 if (p.perm == null || p.perm.info.group == null) {
2035 out.add(generatePermissionInfo(p, flags));
2038 if (p.perm != null && group.equals(p.perm.info.group)) {
2039 out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2044 if (out.size() > 0) {
2047 return mPermissionGroups.containsKey(group) ? out : null;
2052 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2054 synchronized (mPackages) {
2055 return PackageParser.generatePermissionGroupInfo(
2056 mPermissionGroups.get(name), flags);
2061 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2063 synchronized (mPackages) {
2064 final int N = mPermissionGroups.size();
2065 ArrayList<PermissionGroupInfo> out
2066 = new ArrayList<PermissionGroupInfo>(N);
2067 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2068 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2074 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2076 if (!sUserManager.exists(userId)) return null;
2077 PackageSetting ps = mSettings.mPackages.get(packageName);
2079 if (ps.pkg == null) {
2080 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2082 if (pInfo != null) {
2083 return pInfo.applicationInfo;
2087 return PackageParser.generateApplicationInfo(ps.pkg, flags,
2088 ps.readUserState(userId), userId);
2093 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2095 if (!sUserManager.exists(userId)) return null;
2096 PackageSetting ps = mSettings.mPackages.get(packageName);
2098 PackageParser.Package pkg = ps.pkg;
2100 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2103 // Only data remains, so we aren't worried about code paths
2104 pkg = new PackageParser.Package(packageName);
2105 pkg.applicationInfo.packageName = packageName;
2106 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2107 pkg.applicationInfo.dataDir =
2108 getDataPathForPackage(packageName, 0).getPath();
2109 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2110 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2112 return generatePackageInfo(pkg, flags, userId);
2118 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2119 if (!sUserManager.exists(userId)) return null;
2120 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2122 synchronized (mPackages) {
2123 PackageParser.Package p = mPackages.get(packageName);
2124 if (DEBUG_PACKAGE_INFO) Log.v(
2125 TAG, "getApplicationInfo " + packageName
2128 PackageSetting ps = mSettings.mPackages.get(packageName);
2129 if (ps == null) return null;
2130 // Note: isEnabledLP() does not apply here - always return info
2131 return PackageParser.generateApplicationInfo(
2132 p, flags, ps.readUserState(userId), userId);
2134 if ("android".equals(packageName)||"system".equals(packageName)) {
2135 return mAndroidApplication;
2137 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2138 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2146 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
2147 mContext.enforceCallingOrSelfPermission(
2148 android.Manifest.permission.CLEAR_APP_CACHE, null);
2149 // Queue up an async operation since clearing cache may take a little while.
2150 mHandler.post(new Runnable() {
2152 mHandler.removeCallbacks(this);
2154 synchronized (mInstallLock) {
2155 retCode = mInstaller.freeCache(freeStorageSize);
2157 Slog.w(TAG, "Couldn't clear application caches");
2160 if (observer != null) {
2162 observer.onRemoveCompleted(null, (retCode >= 0));
2163 } catch (RemoteException e) {
2164 Slog.w(TAG, "RemoveException when invoking call back");
2172 public void freeStorage(final long freeStorageSize, final IntentSender pi) {
2173 mContext.enforceCallingOrSelfPermission(
2174 android.Manifest.permission.CLEAR_APP_CACHE, null);
2175 // Queue up an async operation since clearing cache may take a little while.
2176 mHandler.post(new Runnable() {
2178 mHandler.removeCallbacks(this);
2180 synchronized (mInstallLock) {
2181 retCode = mInstaller.freeCache(freeStorageSize);
2183 Slog.w(TAG, "Couldn't clear application caches");
2188 // Callback via pending intent
2189 int code = (retCode >= 0) ? 1 : 0;
2190 pi.sendIntent(null, code, null,
2192 } catch (SendIntentException e1) {
2193 Slog.i(TAG, "Failed to send pending intent");
2200 void freeStorage(long freeStorageSize) throws IOException {
2201 synchronized (mInstallLock) {
2202 if (mInstaller.freeCache(freeStorageSize) < 0) {
2203 throw new IOException("Failed to free enough space");
2209 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2210 if (!sUserManager.exists(userId)) return null;
2211 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
2212 synchronized (mPackages) {
2213 PackageParser.Activity a = mActivities.mActivities.get(component);
2215 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2216 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2217 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2218 if (ps == null) return null;
2219 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2222 if (mResolveComponentName.equals(component)) {
2223 return PackageParser.generateActivityInfo(mResolveActivity, flags,
2224 new PackageUserState(), userId);
2231 public boolean activitySupportsIntent(ComponentName component, Intent intent,
2232 String resolvedType) {
2233 synchronized (mPackages) {
2234 PackageParser.Activity a = mActivities.mActivities.get(component);
2238 for (int i=0; i<a.intents.size(); i++) {
2239 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2240 intent.getData(), intent.getCategories(), TAG) >= 0) {
2249 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2250 if (!sUserManager.exists(userId)) return null;
2251 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
2252 synchronized (mPackages) {
2253 PackageParser.Activity a = mReceivers.mActivities.get(component);
2254 if (DEBUG_PACKAGE_INFO) Log.v(
2255 TAG, "getReceiverInfo " + component + ": " + a);
2256 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2257 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2258 if (ps == null) return null;
2259 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2267 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2268 if (!sUserManager.exists(userId)) return null;
2269 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
2270 synchronized (mPackages) {
2271 PackageParser.Service s = mServices.mServices.get(component);
2272 if (DEBUG_PACKAGE_INFO) Log.v(
2273 TAG, "getServiceInfo " + component + ": " + s);
2274 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2275 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2276 if (ps == null) return null;
2277 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2285 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2286 if (!sUserManager.exists(userId)) return null;
2287 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
2288 synchronized (mPackages) {
2289 PackageParser.Provider p = mProviders.mProviders.get(component);
2290 if (DEBUG_PACKAGE_INFO) Log.v(
2291 TAG, "getProviderInfo " + component + ": " + p);
2292 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2293 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2294 if (ps == null) return null;
2295 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2303 public String[] getSystemSharedLibraryNames() {
2305 synchronized (mPackages) {
2306 libSet = mSharedLibraries.keySet();
2307 int size = libSet.size();
2309 String[] libs = new String[size];
2310 libSet.toArray(libs);
2318 public FeatureInfo[] getSystemAvailableFeatures() {
2319 Collection<FeatureInfo> featSet;
2320 synchronized (mPackages) {
2321 featSet = mAvailableFeatures.values();
2322 int size = featSet.size();
2324 FeatureInfo[] features = new FeatureInfo[size+1];
2325 featSet.toArray(features);
2326 FeatureInfo fi = new FeatureInfo();
2327 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2328 FeatureInfo.GL_ES_VERSION_UNDEFINED);
2329 features[size] = fi;
2337 public boolean hasSystemFeature(String name) {
2338 synchronized (mPackages) {
2339 return mAvailableFeatures.containsKey(name);
2343 private void checkValidCaller(int uid, int userId) {
2344 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2347 throw new SecurityException("Caller uid=" + uid
2348 + " is not privileged to communicate with user=" + userId);
2352 public int checkPermission(String permName, String pkgName) {
2353 synchronized (mPackages) {
2354 PackageParser.Package p = mPackages.get(pkgName);
2355 if (p != null && p.mExtras != null) {
2356 PackageSetting ps = (PackageSetting)p.mExtras;
2357 if (ps.sharedUser != null) {
2358 if (ps.sharedUser.grantedPermissions.contains(permName)) {
2359 return PackageManager.PERMISSION_GRANTED;
2361 } else if (ps.grantedPermissions.contains(permName)) {
2362 return PackageManager.PERMISSION_GRANTED;
2366 return PackageManager.PERMISSION_DENIED;
2370 public int checkUidPermission(String permName, int uid) {
2371 synchronized (mPackages) {
2372 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2374 GrantedPermissions gp = (GrantedPermissions)obj;
2375 if (gp.grantedPermissions.contains(permName)) {
2376 return PackageManager.PERMISSION_GRANTED;
2379 HashSet<String> perms = mSystemPermissions.get(uid);
2380 if (perms != null && perms.contains(permName)) {
2381 return PackageManager.PERMISSION_GRANTED;
2385 return PackageManager.PERMISSION_DENIED;
2389 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2390 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2391 * @param checkShell TODO(yamasani):
2392 * @param message the message to log on security exception
2394 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
2395 boolean checkShell, String message) {
2397 throw new IllegalArgumentException("Invalid userId " + userId);
2400 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2402 if (userId == UserHandle.getUserId(callingUid)) return;
2403 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2404 if (requireFullPermission) {
2405 mContext.enforceCallingOrSelfPermission(
2406 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2409 mContext.enforceCallingOrSelfPermission(
2410 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2411 } catch (SecurityException se) {
2412 mContext.enforceCallingOrSelfPermission(
2413 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2419 void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
2420 if (callingUid == Process.SHELL_UID) {
2422 && sUserManager.hasUserRestriction(restriction, userHandle)) {
2423 throw new SecurityException("Shell does not have permission to access user "
2425 } else if (userHandle < 0) {
2426 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
2427 + Debug.getCallers(3));
2432 private BasePermission findPermissionTreeLP(String permName) {
2433 for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2434 if (permName.startsWith(bp.name) &&
2435 permName.length() > bp.name.length() &&
2436 permName.charAt(bp.name.length()) == '.') {
2443 private BasePermission checkPermissionTreeLP(String permName) {
2444 if (permName != null) {
2445 BasePermission bp = findPermissionTreeLP(permName);
2447 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2450 throw new SecurityException("Calling uid "
2451 + Binder.getCallingUid()
2452 + " is not allowed to add to permission tree "
2453 + bp.name + " owned by uid " + bp.uid);
2456 throw new SecurityException("No permission tree found for " + permName);
2459 static boolean compareStrings(CharSequence s1, CharSequence s2) {
2466 if (s1.getClass() != s2.getClass()) {
2469 return s1.equals(s2);
2472 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2473 if (pi1.icon != pi2.icon) return false;
2474 if (pi1.logo != pi2.logo) return false;
2475 if (pi1.protectionLevel != pi2.protectionLevel) return false;
2476 if (!compareStrings(pi1.name, pi2.name)) return false;
2477 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2478 // We'll take care of setting this one.
2479 if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2480 // These are not currently stored in settings.
2481 //if (!compareStrings(pi1.group, pi2.group)) return false;
2482 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2483 //if (pi1.labelRes != pi2.labelRes) return false;
2484 //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2488 int permissionInfoFootprint(PermissionInfo info) {
2489 int size = info.name.length();
2490 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
2491 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
2495 int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2497 for (BasePermission perm : mSettings.mPermissions.values()) {
2498 if (perm.uid == tree.uid) {
2499 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
2505 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2506 // We calculate the max size of permissions defined by this uid and throw
2507 // if that plus the size of 'info' would exceed our stated maximum.
2508 if (tree.uid != Process.SYSTEM_UID) {
2509 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2510 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
2511 throw new SecurityException("Permission tree size cap exceeded");
2516 boolean addPermissionLocked(PermissionInfo info, boolean async) {
2517 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2518 throw new SecurityException("Label must be specified in permission");
2520 BasePermission tree = checkPermissionTreeLP(info.name);
2521 BasePermission bp = mSettings.mPermissions.get(info.name);
2522 boolean added = bp == null;
2523 boolean changed = true;
2524 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2526 enforcePermissionCapLocked(info, tree);
2527 bp = new BasePermission(info.name, tree.sourcePackage,
2528 BasePermission.TYPE_DYNAMIC);
2529 } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2530 throw new SecurityException(
2531 "Not allowed to modify non-dynamic permission "
2534 if (bp.protectionLevel == fixedLevel
2535 && bp.perm.owner.equals(tree.perm.owner)
2536 && bp.uid == tree.uid
2537 && comparePermissionInfos(bp.perm.info, info)) {
2541 bp.protectionLevel = fixedLevel;
2542 info = new PermissionInfo(info);
2543 info.protectionLevel = fixedLevel;
2544 bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2545 bp.perm.info.packageName = tree.perm.info.packageName;
2548 mSettings.mPermissions.put(info.name, bp);
2552 mSettings.writeLPr();
2554 scheduleWriteSettingsLocked();
2561 public boolean addPermission(PermissionInfo info) {
2562 synchronized (mPackages) {
2563 return addPermissionLocked(info, false);
2568 public boolean addPermissionAsync(PermissionInfo info) {
2569 synchronized (mPackages) {
2570 return addPermissionLocked(info, true);
2575 public void removePermission(String name) {
2576 synchronized (mPackages) {
2577 checkPermissionTreeLP(name);
2578 BasePermission bp = mSettings.mPermissions.get(name);
2580 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2581 throw new SecurityException(
2582 "Not allowed to modify non-dynamic permission "
2585 mSettings.mPermissions.remove(name);
2586 mSettings.writeLPr();
2591 private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2592 int index = pkg.requestedPermissions.indexOf(bp.name);
2594 throw new SecurityException("Package " + pkg.packageName
2595 + " has not requested permission " + bp.name);
2598 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2599 == PermissionInfo.PROTECTION_NORMAL);
2600 boolean isDangerous =
2601 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2602 == PermissionInfo.PROTECTION_DANGEROUS);
2603 boolean isDevelopment =
2604 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2606 if (!isNormal && !isDangerous && !isDevelopment) {
2607 throw new SecurityException("Permission " + bp.name
2608 + " is not a changeable permission type");
2611 if (isNormal || isDangerous) {
2612 if (pkg.requestedPermissionsRequired.get(index)) {
2613 throw new SecurityException("Can't change " + bp.name
2614 + ". It is required by the application");
2620 public void grantPermission(String packageName, String permissionName) {
2621 mContext.enforceCallingOrSelfPermission(
2622 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2623 synchronized (mPackages) {
2624 final PackageParser.Package pkg = mPackages.get(packageName);
2626 throw new IllegalArgumentException("Unknown package: " + packageName);
2628 final BasePermission bp = mSettings.mPermissions.get(permissionName);
2630 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2633 checkGrantRevokePermissions(pkg, bp);
2635 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2639 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2640 if (gp.grantedPermissions.add(permissionName)) {
2642 gp.gids = appendInts(gp.gids, bp.gids);
2644 mSettings.writeLPr();
2650 public void revokePermission(String packageName, String permissionName) {
2651 int changedAppId = -1;
2653 synchronized (mPackages) {
2654 final PackageParser.Package pkg = mPackages.get(packageName);
2656 throw new IllegalArgumentException("Unknown package: " + packageName);
2658 if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2659 mContext.enforceCallingOrSelfPermission(
2660 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2662 final BasePermission bp = mSettings.mPermissions.get(permissionName);
2664 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2667 checkGrantRevokePermissions(pkg, bp);
2669 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2673 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2674 if (gp.grantedPermissions.remove(permissionName)) {
2675 gp.grantedPermissions.remove(permissionName);
2677 gp.gids = removeInts(gp.gids, bp.gids);
2679 mSettings.writeLPr();
2680 changedAppId = ps.appId;
2684 if (changedAppId >= 0) {
2685 // We changed the perm on someone, kill its processes.
2686 IActivityManager am = ActivityManagerNative.getDefault();
2688 final int callingUserId = UserHandle.getCallingUserId();
2689 final long ident = Binder.clearCallingIdentity();
2691 //XXX we should only revoke for the calling user's app permissions,
2692 // but for now we impact all users.
2693 //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2694 // "revoke " + permissionName);
2695 int[] users = sUserManager.getUserIds();
2696 for (int user : users) {
2697 am.killUid(UserHandle.getUid(user, changedAppId),
2698 "revoke " + permissionName);
2700 } catch (RemoteException e) {
2702 Binder.restoreCallingIdentity(ident);
2709 public boolean isProtectedBroadcast(String actionName) {
2710 synchronized (mPackages) {
2711 return mProtectedBroadcasts.contains(actionName);
2716 public int checkSignatures(String pkg1, String pkg2) {
2717 synchronized (mPackages) {
2718 final PackageParser.Package p1 = mPackages.get(pkg1);
2719 final PackageParser.Package p2 = mPackages.get(pkg2);
2720 if (p1 == null || p1.mExtras == null
2721 || p2 == null || p2.mExtras == null) {
2722 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2724 return compareSignatures(p1.mSignatures, p2.mSignatures);
2729 public int checkUidSignatures(int uid1, int uid2) {
2730 // Map to base uids.
2731 uid1 = UserHandle.getAppId(uid1);
2732 uid2 = UserHandle.getAppId(uid2);
2734 synchronized (mPackages) {
2737 Object obj = mSettings.getUserIdLPr(uid1);
2739 if (obj instanceof SharedUserSetting) {
2740 s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2741 } else if (obj instanceof PackageSetting) {
2742 s1 = ((PackageSetting)obj).signatures.mSignatures;
2744 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2747 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2749 obj = mSettings.getUserIdLPr(uid2);
2751 if (obj instanceof SharedUserSetting) {
2752 s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2753 } else if (obj instanceof PackageSetting) {
2754 s2 = ((PackageSetting)obj).signatures.mSignatures;
2756 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2759 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2761 return compareSignatures(s1, s2);
2766 * Compares two sets of signatures. Returns:
2768 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
2770 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
2772 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
2774 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
2776 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
2778 static int compareSignatures(Signature[] s1, Signature[] s2) {
2781 ? PackageManager.SIGNATURE_NEITHER_SIGNED
2782 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2786 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2789 if (s1.length != s2.length) {
2790 return PackageManager.SIGNATURE_NO_MATCH;
2793 // Since both signature sets are of size 1, we can compare without HashSets.
2794 if (s1.length == 1) {
2795 return s1[0].equals(s2[0]) ?
2796 PackageManager.SIGNATURE_MATCH :
2797 PackageManager.SIGNATURE_NO_MATCH;
2800 HashSet<Signature> set1 = new HashSet<Signature>();
2801 for (Signature sig : s1) {
2804 HashSet<Signature> set2 = new HashSet<Signature>();
2805 for (Signature sig : s2) {
2808 // Make sure s2 contains all signatures in s1.
2809 if (set1.equals(set2)) {
2810 return PackageManager.SIGNATURE_MATCH;
2812 return PackageManager.SIGNATURE_NO_MATCH;
2816 * If the database version for this type of package (internal storage or
2817 * external storage) is less than the version where package signatures
2818 * were updated, return true.
2820 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
2821 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
2822 DatabaseVersion.SIGNATURE_END_ENTITY))
2823 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
2824 DatabaseVersion.SIGNATURE_END_ENTITY));
2828 * Used for backward compatibility to make sure any packages with
2829 * certificate chains get upgraded to the new style. {@code existingSigs}
2830 * will be in the old format (since they were stored on disk from before the
2831 * system upgrade) and {@code scannedSigs} will be in the newer format.
2833 private int compareSignaturesCompat(PackageSignatures existingSigs,
2834 PackageParser.Package scannedPkg) {
2835 if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
2836 return PackageManager.SIGNATURE_NO_MATCH;
2839 HashSet<Signature> existingSet = new HashSet<Signature>();
2840 for (Signature sig : existingSigs.mSignatures) {
2841 existingSet.add(sig);
2843 HashSet<Signature> scannedCompatSet = new HashSet<Signature>();
2844 for (Signature sig : scannedPkg.mSignatures) {
2846 Signature[] chainSignatures = sig.getChainSignatures();
2847 for (Signature chainSig : chainSignatures) {
2848 scannedCompatSet.add(chainSig);
2850 } catch (CertificateEncodingException e) {
2851 scannedCompatSet.add(sig);
2855 * Make sure the expanded scanned set contains all signatures in the
2858 if (scannedCompatSet.equals(existingSet)) {
2859 // Migrate the old signatures to the new scheme.
2860 existingSigs.assignSignatures(scannedPkg.mSignatures);
2861 // The new KeySets will be re-added later in the scanning process.
2862 synchronized (mPackages) {
2863 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
2865 return PackageManager.SIGNATURE_MATCH;
2867 return PackageManager.SIGNATURE_NO_MATCH;
2871 public String[] getPackagesForUid(int uid) {
2872 uid = UserHandle.getAppId(uid);
2874 synchronized (mPackages) {
2875 Object obj = mSettings.getUserIdLPr(uid);
2876 if (obj instanceof SharedUserSetting) {
2877 final SharedUserSetting sus = (SharedUserSetting) obj;
2878 final int N = sus.packages.size();
2879 final String[] res = new String[N];
2880 final Iterator<PackageSetting> it = sus.packages.iterator();
2882 while (it.hasNext()) {
2883 res[i++] = it.next().name;
2886 } else if (obj instanceof PackageSetting) {
2887 final PackageSetting ps = (PackageSetting) obj;
2888 return new String[] { ps.name };
2895 public String getNameForUid(int uid) {
2897 synchronized (mPackages) {
2898 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2899 if (obj instanceof SharedUserSetting) {
2900 final SharedUserSetting sus = (SharedUserSetting) obj;
2901 return sus.name + ":" + sus.userId;
2902 } else if (obj instanceof PackageSetting) {
2903 final PackageSetting ps = (PackageSetting) obj;
2911 public int getUidForSharedUser(String sharedUserName) {
2912 if(sharedUserName == null) {
2916 synchronized (mPackages) {
2917 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2926 public int getFlagsForUid(int uid) {
2927 synchronized (mPackages) {
2928 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2929 if (obj instanceof SharedUserSetting) {
2930 final SharedUserSetting sus = (SharedUserSetting) obj;
2931 return sus.pkgFlags;
2932 } else if (obj instanceof PackageSetting) {
2933 final PackageSetting ps = (PackageSetting) obj;
2941 public boolean isUidPrivileged(int uid) {
2942 uid = UserHandle.getAppId(uid);
2944 synchronized (mPackages) {
2945 Object obj = mSettings.getUserIdLPr(uid);
2946 if (obj instanceof SharedUserSetting) {
2947 final SharedUserSetting sus = (SharedUserSetting) obj;
2948 final Iterator<PackageSetting> it = sus.packages.iterator();
2949 while (it.hasNext()) {
2950 if (it.next().isPrivileged()) {
2954 } else if (obj instanceof PackageSetting) {
2955 final PackageSetting ps = (PackageSetting) obj;
2956 return ps.isPrivileged();
2963 public String[] getAppOpPermissionPackages(String permissionName) {
2964 synchronized (mPackages) {
2965 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
2969 return pkgs.toArray(new String[pkgs.size()]);
2974 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2975 int flags, int userId) {
2976 if (!sUserManager.exists(userId)) return null;
2977 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
2978 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2979 return chooseBestActivity(intent, resolvedType, flags, query, userId);
2983 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
2984 IntentFilter filter, int match, ComponentName activity) {
2985 final int userId = UserHandle.getCallingUserId();
2986 if (DEBUG_PREFERRED) {
2987 Log.v(TAG, "setLastChosenActivity intent=" + intent
2988 + " resolvedType=" + resolvedType
2990 + " filter=" + filter
2992 + " activity=" + activity);
2993 filter.dump(new PrintStreamPrinter(System.out), " ");
2995 intent.setComponent(null);
2996 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2997 // Find any earlier preferred or last chosen entries and nuke them
2998 findPreferredActivity(intent, resolvedType,
2999 flags, query, 0, false, true, false, userId);
3000 // Add the new activity as the last chosen for this filter
3001 addPreferredActivityInternal(filter, match, null, activity, false, userId,
3002 "Setting last chosen");
3006 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
3007 final int userId = UserHandle.getCallingUserId();
3008 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
3009 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3010 return findPreferredActivity(intent, resolvedType, flags, query, 0,
3011 false, false, false, userId);
3014 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
3015 int flags, List<ResolveInfo> query, int userId) {
3016 if (query != null) {
3017 final int N = query.size();
3019 return query.get(0);
3021 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3022 // If there is more than one activity with the same priority,
3023 // then let the user decide between them.
3024 ResolveInfo r0 = query.get(0);
3025 ResolveInfo r1 = query.get(1);
3026 if (DEBUG_INTENT_MATCHING || debug) {
3027 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
3028 + r1.activityInfo.name + "=" + r1.priority);
3030 // If the first activity has a higher priority, or a different
3031 // default, then it is always desireable to pick it.
3032 if (r0.priority != r1.priority
3033 || r0.preferredOrder != r1.preferredOrder
3034 || r0.isDefault != r1.isDefault) {
3035 return query.get(0);
3037 // If we have saved a preference for a preferred activity for
3038 // this Intent, use that.
3039 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
3040 flags, query, r0.priority, true, false, debug, userId);
3045 ri = new ResolveInfo(mResolveInfo);
3046 ri.activityInfo = new ActivityInfo(ri.activityInfo);
3047 ri.activityInfo.applicationInfo = new ApplicationInfo(
3048 ri.activityInfo.applicationInfo);
3049 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
3050 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
3053 return mResolveInfo;
3059 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
3060 int flags, List<ResolveInfo> query, boolean debug, int userId) {
3061 final int N = query.size();
3062 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
3064 // Get the list of persistent preferred activities that handle the intent
3065 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
3066 List<PersistentPreferredActivity> pprefs = ppir != null
3067 ? ppir.queryIntent(intent, resolvedType,
3068 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3070 if (pprefs != null && pprefs.size() > 0) {
3071 final int M = pprefs.size();
3072 for (int i=0; i<M; i++) {
3073 final PersistentPreferredActivity ppa = pprefs.get(i);
3074 if (DEBUG_PREFERRED || debug) {
3075 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
3076 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
3077 + "\n component=" + ppa.mComponent);
3078 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3080 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
3081 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3082 if (DEBUG_PREFERRED || debug) {
3083 Slog.v(TAG, "Found persistent preferred activity:");
3085 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3087 Slog.v(TAG, " null");
3091 // This previously registered persistent preferred activity
3092 // component is no longer known. Ignore it and do NOT remove it.
3095 for (int j=0; j<N; j++) {
3096 final ResolveInfo ri = query.get(j);
3097 if (!ri.activityInfo.applicationInfo.packageName
3098 .equals(ai.applicationInfo.packageName)) {
3101 if (!ri.activityInfo.name.equals(ai.name)) {
3104 // Found a persistent preference that can handle the intent.
3105 if (DEBUG_PREFERRED || debug) {
3106 Slog.v(TAG, "Returning persistent preferred activity: " +
3107 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3116 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
3117 List<ResolveInfo> query, int priority, boolean always,
3118 boolean removeMatches, boolean debug, int userId) {
3119 if (!sUserManager.exists(userId)) return null;
3121 synchronized (mPackages) {
3122 if (intent.getSelector() != null) {
3123 intent = intent.getSelector();
3125 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
3127 // Try to find a matching persistent preferred activity.
3128 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
3131 // If a persistent preferred activity matched, use it.
3136 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
3137 // Get the list of preferred activities that handle the intent
3138 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
3139 List<PreferredActivity> prefs = pir != null
3140 ? pir.queryIntent(intent, resolvedType,
3141 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3143 if (prefs != null && prefs.size() > 0) {
3144 boolean changed = false;
3146 // First figure out how good the original match set is.
3147 // We will only allow preferred activities that came
3148 // from the same match quality.
3151 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
3153 final int N = query.size();
3154 for (int j=0; j<N; j++) {
3155 final ResolveInfo ri = query.get(j);
3156 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
3157 + ": 0x" + Integer.toHexString(match));
3158 if (ri.match > match) {
3163 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
3164 + Integer.toHexString(match));
3166 match &= IntentFilter.MATCH_CATEGORY_MASK;
3167 final int M = prefs.size();
3168 for (int i=0; i<M; i++) {
3169 final PreferredActivity pa = prefs.get(i);
3170 if (DEBUG_PREFERRED || debug) {
3171 Slog.v(TAG, "Checking PreferredActivity ds="
3172 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
3173 + "\n component=" + pa.mPref.mComponent);
3174 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3176 if (pa.mPref.mMatch != match) {
3177 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
3178 + Integer.toHexString(pa.mPref.mMatch));
3181 // If it's not an "always" type preferred activity and that's what we're
3182 // looking for, skip it.
3183 if (always && !pa.mPref.mAlways) {
3184 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
3187 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
3188 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3189 if (DEBUG_PREFERRED || debug) {
3190 Slog.v(TAG, "Found preferred activity:");
3192 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3194 Slog.v(TAG, " null");
3198 // This previously registered preferred activity
3199 // component is no longer known. Most likely an update
3200 // to the app was installed and in the new version this
3201 // component no longer exists. Clean it up by removing
3202 // it from the preferred activities list, and skip it.
3203 Slog.w(TAG, "Removing dangling preferred activity: "
3204 + pa.mPref.mComponent);
3205 pir.removeFilter(pa);
3209 for (int j=0; j<N; j++) {
3210 final ResolveInfo ri = query.get(j);
3211 if (!ri.activityInfo.applicationInfo.packageName
3212 .equals(ai.applicationInfo.packageName)) {
3215 if (!ri.activityInfo.name.equals(ai.name)) {
3219 if (removeMatches) {
3220 pir.removeFilter(pa);
3222 if (DEBUG_PREFERRED) {
3223 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
3228 // Okay we found a previously set preferred or last chosen app.
3229 // If the result set is different from when this
3230 // was created, we need to clear it and re-ask the
3231 // user their preference, if we're looking for an "always" type entry.
3232 if (always && !pa.mPref.sameSet(query, priority)) {
3233 Slog.i(TAG, "Result set changed, dropping preferred activity for "
3234 + intent + " type " + resolvedType);
3235 if (DEBUG_PREFERRED) {
3236 Slog.v(TAG, "Removing preferred activity since set changed "
3237 + pa.mPref.mComponent);
3239 pir.removeFilter(pa);
3240 // Re-add the filter as a "last chosen" entry (!always)
3241 PreferredActivity lastChosen = new PreferredActivity(
3242 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
3243 pir.addFilter(lastChosen);
3248 // Yay! Either the set matched or we're looking for the last chosen
3249 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
3250 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3256 if (DEBUG_PREFERRED) {
3257 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
3259 mSettings.writePackageRestrictionsLPr(userId);
3264 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
3269 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
3272 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
3274 mContext.enforceCallingOrSelfPermission(
3275 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
3276 List<CrossProfileIntentFilter> matches =
3277 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
3278 if (matches != null) {
3279 int size = matches.size();
3280 for (int i = 0; i < size; i++) {
3281 if (matches.get(i).getTargetUserId() == targetUserId) return true;
3287 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
3288 String resolvedType, int userId) {
3289 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
3290 if (resolver != null) {
3291 return resolver.queryIntent(intent, resolvedType, false, userId);
3297 public List<ResolveInfo> queryIntentActivities(Intent intent,
3298 String resolvedType, int flags, int userId) {
3299 if (!sUserManager.exists(userId)) return Collections.emptyList();
3300 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
3301 ComponentName comp = intent.getComponent();
3303 if (intent.getSelector() != null) {
3304 intent = intent.getSelector();
3305 comp = intent.getComponent();
3310 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3311 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
3313 final ResolveInfo ri = new ResolveInfo();
3314 ri.activityInfo = ai;
3321 synchronized (mPackages) {
3322 final String pkgName = intent.getPackage();
3323 if (pkgName == null) {
3324 List<CrossProfileIntentFilter> matchingFilters =
3325 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
3326 // Check for results that need to skip the current profile.
3327 ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
3328 resolvedType, flags, userId);
3329 if (resolveInfo != null) {
3330 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
3331 result.add(resolveInfo);
3334 // Check for cross profile results.
3335 resolveInfo = queryCrossProfileIntents(
3336 matchingFilters, intent, resolvedType, flags, userId);
3338 // Check for results in the current profile.
3339 List<ResolveInfo> result = mActivities.queryIntent(
3340 intent, resolvedType, flags, userId);
3341 if (resolveInfo != null) {
3342 result.add(resolveInfo);
3343 Collections.sort(result, mResolvePrioritySorter);
3347 final PackageParser.Package pkg = mPackages.get(pkgName);
3349 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
3350 pkg.activities, userId);
3352 return new ArrayList<ResolveInfo>();
3356 private ResolveInfo querySkipCurrentProfileIntents(
3357 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3358 int flags, int sourceUserId) {
3359 if (matchingFilters != null) {
3360 int size = matchingFilters.size();
3361 for (int i = 0; i < size; i ++) {
3362 CrossProfileIntentFilter filter = matchingFilters.get(i);
3363 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
3364 // Checking if there are activities in the target user that can handle the
3366 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3367 flags, sourceUserId);
3368 if (resolveInfo != null) {
3377 // Return matching ResolveInfo if any for skip current profile intent filters.
3378 private ResolveInfo queryCrossProfileIntents(
3379 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3380 int flags, int sourceUserId) {
3381 if (matchingFilters != null) {
3382 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
3383 // match the same intent. For performance reasons, it is better not to
3384 // run queryIntent twice for the same userId
3385 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
3386 int size = matchingFilters.size();
3387 for (int i = 0; i < size; i++) {
3388 CrossProfileIntentFilter filter = matchingFilters.get(i);
3389 int targetUserId = filter.getTargetUserId();
3390 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
3391 && !alreadyTriedUserIds.get(targetUserId)) {
3392 // Checking if there are activities in the target user that can handle the
3394 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3395 flags, sourceUserId);
3396 if (resolveInfo != null) return resolveInfo;
3397 alreadyTriedUserIds.put(targetUserId, true);
3404 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
3405 String resolvedType, int flags, int sourceUserId) {
3406 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
3407 resolvedType, flags, filter.getTargetUserId());
3408 if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
3409 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
3414 private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
3415 int sourceUserId, int targetUserId) {
3416 ResolveInfo forwardingResolveInfo = new ResolveInfo();
3418 if (targetUserId == UserHandle.USER_OWNER) {
3419 className = FORWARD_INTENT_TO_USER_OWNER;
3421 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3423 ComponentName forwardingActivityComponentName = new ComponentName(
3424 mAndroidApplication.packageName, className);
3425 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
3427 if (targetUserId == UserHandle.USER_OWNER) {
3428 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
3429 forwardingResolveInfo.noResourceId = true;
3431 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3432 forwardingResolveInfo.priority = 0;
3433 forwardingResolveInfo.preferredOrder = 0;
3434 forwardingResolveInfo.match = 0;
3435 forwardingResolveInfo.isDefault = true;
3436 forwardingResolveInfo.filter = filter;
3437 forwardingResolveInfo.targetUserId = targetUserId;
3438 return forwardingResolveInfo;
3442 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
3443 Intent[] specifics, String[] specificTypes, Intent intent,
3444 String resolvedType, int flags, int userId) {
3445 if (!sUserManager.exists(userId)) return Collections.emptyList();
3446 enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
3447 false, "query intent activity options");
3448 final String resultsAction = intent.getAction();
3450 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
3451 | PackageManager.GET_RESOLVED_FILTER, userId);
3453 if (DEBUG_INTENT_MATCHING) {
3454 Log.v(TAG, "Query " + intent + ": " + results);
3457 int specificsPos = 0;
3460 // todo: note that the algorithm used here is O(N^2). This
3461 // isn't a problem in our current environment, but if we start running
3462 // into situations where we have more than 5 or 10 matches then this
3463 // should probably be changed to something smarter...
3465 // First we go through and resolve each of the specific items
3466 // that were supplied, taking care of removing any corresponding
3467 // duplicate items in the generic resolve list.
3468 if (specifics != null) {
3469 for (int i=0; i<specifics.length; i++) {
3470 final Intent sintent = specifics[i];
3471 if (sintent == null) {
3475 if (DEBUG_INTENT_MATCHING) {
3476 Log.v(TAG, "Specific #" + i + ": " + sintent);
3479 String action = sintent.getAction();
3480 if (resultsAction != null && resultsAction.equals(action)) {
3481 // If this action was explicitly requested, then don't
3482 // remove things that have it.
3486 ResolveInfo ri = null;
3487 ActivityInfo ai = null;
3489 ComponentName comp = sintent.getComponent();
3493 specificTypes != null ? specificTypes[i] : null,
3498 if (ri == mResolveInfo) {
3499 // ACK! Must do something better with this.
3501 ai = ri.activityInfo;
3502 comp = new ComponentName(ai.applicationInfo.packageName,
3505 ai = getActivityInfo(comp, flags, userId);
3511 // Look for any generic query activities that are duplicates
3512 // of this specific one, and remove them from the results.
3513 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
3516 for (j=specificsPos; j<N; j++) {
3517 ResolveInfo sri = results.get(j);
3518 if ((sri.activityInfo.name.equals(comp.getClassName())
3519 && sri.activityInfo.applicationInfo.packageName.equals(
3520 comp.getPackageName()))
3521 || (action != null && sri.filter.matchAction(action))) {
3523 if (DEBUG_INTENT_MATCHING) Log.v(
3524 TAG, "Removing duplicate item from " + j
3525 + " due to specific " + specificsPos);
3534 // Add this specific item to its proper place.
3536 ri = new ResolveInfo();
3537 ri.activityInfo = ai;
3539 results.add(specificsPos, ri);
3540 ri.specificIndex = i;
3545 // Now we go through the remaining generic results and remove any
3546 // duplicate actions that are found here.
3548 for (int i=specificsPos; i<N-1; i++) {
3549 final ResolveInfo rii = results.get(i);
3550 if (rii.filter == null) {
3554 // Iterate over all of the actions of this result's intent
3555 // filter... typically this should be just one.
3556 final Iterator<String> it = rii.filter.actionsIterator();
3560 while (it.hasNext()) {
3561 final String action = it.next();
3562 if (resultsAction != null && resultsAction.equals(action)) {
3563 // If this action was explicitly requested, then don't
3564 // remove things that have it.
3567 for (int j=i+1; j<N; j++) {
3568 final ResolveInfo rij = results.get(j);
3569 if (rij.filter != null && rij.filter.hasAction(action)) {
3571 if (DEBUG_INTENT_MATCHING) Log.v(
3572 TAG, "Removing duplicate item from " + j
3573 + " due to action " + action + " at " + i);
3580 // If the caller didn't request filter information, drop it now
3581 // so we don't have to marshall/unmarshall it.
3582 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3587 // Filter out the caller activity if so requested.
3588 if (caller != null) {
3590 for (int i=0; i<N; i++) {
3591 ActivityInfo ainfo = results.get(i).activityInfo;
3592 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
3593 && caller.getClassName().equals(ainfo.name)) {
3600 // If the caller didn't request filter information,
3601 // drop them now so we don't have to
3602 // marshall/unmarshall it.
3603 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3605 for (int i=0; i<N; i++) {
3606 results.get(i).filter = null;
3610 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
3615 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
3617 if (!sUserManager.exists(userId)) return Collections.emptyList();
3618 ComponentName comp = intent.getComponent();
3620 if (intent.getSelector() != null) {
3621 intent = intent.getSelector();
3622 comp = intent.getComponent();
3626 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3627 ActivityInfo ai = getReceiverInfo(comp, flags, userId);
3629 ResolveInfo ri = new ResolveInfo();
3630 ri.activityInfo = ai;
3637 synchronized (mPackages) {
3638 String pkgName = intent.getPackage();
3639 if (pkgName == null) {
3640 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
3642 final PackageParser.Package pkg = mPackages.get(pkgName);
3644 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
3652 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
3653 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
3654 if (!sUserManager.exists(userId)) return null;
3655 if (query != null) {
3656 if (query.size() >= 1) {
3657 // If there is more than one service with the same priority,
3658 // just arbitrarily pick the first one.
3659 return query.get(0);
3666 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
3668 if (!sUserManager.exists(userId)) return Collections.emptyList();
3669 ComponentName comp = intent.getComponent();
3671 if (intent.getSelector() != null) {
3672 intent = intent.getSelector();
3673 comp = intent.getComponent();
3677 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3678 final ServiceInfo si = getServiceInfo(comp, flags, userId);
3680 final ResolveInfo ri = new ResolveInfo();
3681 ri.serviceInfo = si;
3688 synchronized (mPackages) {
3689 String pkgName = intent.getPackage();
3690 if (pkgName == null) {
3691 return mServices.queryIntent(intent, resolvedType, flags, userId);
3693 final PackageParser.Package pkg = mPackages.get(pkgName);
3695 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3703 public List<ResolveInfo> queryIntentContentProviders(
3704 Intent intent, String resolvedType, int flags, int userId) {
3705 if (!sUserManager.exists(userId)) return Collections.emptyList();
3706 ComponentName comp = intent.getComponent();
3708 if (intent.getSelector() != null) {
3709 intent = intent.getSelector();
3710 comp = intent.getComponent();
3714 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3715 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
3717 final ResolveInfo ri = new ResolveInfo();
3718 ri.providerInfo = pi;
3725 synchronized (mPackages) {
3726 String pkgName = intent.getPackage();
3727 if (pkgName == null) {
3728 return mProviders.queryIntent(intent, resolvedType, flags, userId);
3730 final PackageParser.Package pkg = mPackages.get(pkgName);
3732 return mProviders.queryIntentForPackage(
3733 intent, resolvedType, flags, pkg.providers, userId);
3740 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3741 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3743 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
3746 synchronized (mPackages) {
3747 ArrayList<PackageInfo> list;
3748 if (listUninstalled) {
3749 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3750 for (PackageSetting ps : mSettings.mPackages.values()) {
3752 if (ps.pkg != null) {
3753 pi = generatePackageInfo(ps.pkg, flags, userId);
3755 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3762 list = new ArrayList<PackageInfo>(mPackages.size());
3763 for (PackageParser.Package p : mPackages.values()) {
3764 PackageInfo pi = generatePackageInfo(p, flags, userId);
3771 return new ParceledListSlice<PackageInfo>(list);
3775 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3776 String[] permissions, boolean[] tmp, int flags, int userId) {
3778 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3779 for (int i=0; i<permissions.length; i++) {
3780 if (gp.grantedPermissions.contains(permissions[i])) {
3787 if (numMatch == 0) {
3791 if (ps.pkg != null) {
3792 pi = generatePackageInfo(ps.pkg, flags, userId);
3794 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3796 // The above might return null in cases of uninstalled apps or install-state
3797 // skew across users/profiles.
3799 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3800 if (numMatch == permissions.length) {
3801 pi.requestedPermissions = permissions;
3803 pi.requestedPermissions = new String[numMatch];
3805 for (int i=0; i<permissions.length; i++) {
3807 pi.requestedPermissions[numMatch] = permissions[i];
3818 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3819 String[] permissions, int flags, int userId) {
3820 if (!sUserManager.exists(userId)) return null;
3821 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3824 synchronized (mPackages) {
3825 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3826 boolean[] tmpBools = new boolean[permissions.length];
3827 if (listUninstalled) {
3828 for (PackageSetting ps : mSettings.mPackages.values()) {
3829 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3832 for (PackageParser.Package pkg : mPackages.values()) {
3833 PackageSetting ps = (PackageSetting)pkg.mExtras;
3835 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3841 return new ParceledListSlice<PackageInfo>(list);
3846 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3847 if (!sUserManager.exists(userId)) return null;
3848 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3851 synchronized (mPackages) {
3852 ArrayList<ApplicationInfo> list;
3853 if (listUninstalled) {
3854 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3855 for (PackageSetting ps : mSettings.mPackages.values()) {
3857 if (ps.pkg != null) {
3858 ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3859 ps.readUserState(userId), userId);
3861 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3868 list = new ArrayList<ApplicationInfo>(mPackages.size());
3869 for (PackageParser.Package p : mPackages.values()) {
3870 if (p.mExtras != null) {
3871 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3872 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3880 return new ParceledListSlice<ApplicationInfo>(list);
3884 public List<ApplicationInfo> getPersistentApplications(int flags) {
3885 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3888 synchronized (mPackages) {
3889 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3890 final int userId = UserHandle.getCallingUserId();
3891 while (i.hasNext()) {
3892 final PackageParser.Package p = i.next();
3893 if (p.applicationInfo != null
3894 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3895 && (!mSafeMode || isSystemApp(p))) {
3896 PackageSetting ps = mSettings.mPackages.get(p.packageName);
3898 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3899 ps.readUserState(userId), userId);
3912 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3913 if (!sUserManager.exists(userId)) return null;
3915 synchronized (mPackages) {
3916 final PackageParser.Provider provider = mProvidersByAuthority.get(name);
3917 PackageSetting ps = provider != null
3918 ? mSettings.mPackages.get(provider.owner.packageName)
3921 && mSettings.isEnabledLPr(provider.info, flags, userId)
3922 && (!mSafeMode || (provider.info.applicationInfo.flags
3923 &ApplicationInfo.FLAG_SYSTEM) != 0)
3924 ? PackageParser.generateProviderInfo(provider, flags,
3925 ps.readUserState(userId), userId)
3934 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3936 synchronized (mPackages) {
3937 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
3938 .entrySet().iterator();
3939 final int userId = UserHandle.getCallingUserId();
3940 while (i.hasNext()) {
3941 Map.Entry<String, PackageParser.Provider> entry = i.next();
3942 PackageParser.Provider p = entry.getValue();
3943 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3945 if (ps != null && p.syncable
3946 && (!mSafeMode || (p.info.applicationInfo.flags
3947 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3948 ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3949 ps.readUserState(userId), userId);
3951 outNames.add(entry.getKey());
3960 public List<ProviderInfo> queryContentProviders(String processName,
3961 int uid, int flags) {
3962 ArrayList<ProviderInfo> finalList = null;
3964 synchronized (mPackages) {
3965 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
3966 final int userId = processName != null ?
3967 UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3968 while (i.hasNext()) {
3969 final PackageParser.Provider p = i.next();
3970 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3971 if (ps != null && p.info.authority != null
3972 && (processName == null
3973 || (p.info.processName.equals(processName)
3974 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3975 && mSettings.isEnabledLPr(p.info, flags, userId)
3977 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3978 if (finalList == null) {
3979 finalList = new ArrayList<ProviderInfo>(3);
3981 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3982 ps.readUserState(userId), userId);
3984 finalList.add(info);
3990 if (finalList != null) {
3991 Collections.sort(finalList, mProviderInitOrderSorter);
3998 public InstrumentationInfo getInstrumentationInfo(ComponentName name,
4001 synchronized (mPackages) {
4002 final PackageParser.Instrumentation i = mInstrumentation.get(name);
4003 return PackageParser.generateInstrumentationInfo(i, flags);
4008 public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
4010 ArrayList<InstrumentationInfo> finalList =
4011 new ArrayList<InstrumentationInfo>();
4014 synchronized (mPackages) {
4015 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
4016 while (i.hasNext()) {
4017 final PackageParser.Instrumentation p = i.next();
4018 if (targetPackage == null
4019 || targetPackage.equals(p.info.targetPackage)) {
4020 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
4032 private void createIdmapsForPackageLI(PackageParser.Package pkg) {
4033 HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
4034 if (overlays == null) {
4035 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
4038 for (PackageParser.Package opkg : overlays.values()) {
4039 // Not much to do if idmap fails: we already logged the error
4040 // and we certainly don't want to abort installation of pkg simply
4041 // because an overlay didn't fit properly. For these reasons,
4042 // ignore the return value of createIdmapForPackagePairLI.
4043 createIdmapForPackagePairLI(pkg, opkg);
4047 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
4048 PackageParser.Package opkg) {
4049 if (!opkg.mTrustedOverlay) {
4050 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
4051 opkg.baseCodePath + ": overlay not trusted");
4054 HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
4055 if (overlaySet == null) {
4056 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
4057 opkg.baseCodePath + " but target package has no known overlays");
4060 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4061 // TODO: generate idmap for split APKs
4062 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
4063 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
4064 + opkg.baseCodePath);
4067 PackageParser.Package[] overlayArray =
4068 overlaySet.values().toArray(new PackageParser.Package[0]);
4069 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
4070 public int compare(PackageParser.Package p1, PackageParser.Package p2) {
4071 return p1.mOverlayPriority - p2.mOverlayPriority;
4074 Arrays.sort(overlayArray, cmp);
4076 pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
4078 for (PackageParser.Package p : overlayArray) {
4079 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
4084 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
4085 final File[] files = dir.listFiles();
4086 if (ArrayUtils.isEmpty(files)) {
4087 Log.d(TAG, "No files in app dir " + dir);
4091 if (DEBUG_PACKAGE_SCANNING) {
4092 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
4093 + " flags=0x" + Integer.toHexString(parseFlags));
4096 for (File file : files) {
4097 final boolean isPackage = (isApkFile(file) || file.isDirectory())
4098 && !PackageInstallerService.isStageName(file.getName());
4100 // Ignore entries which are not packages
4104 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
4105 scanFlags, currentTime, null);
4106 } catch (PackageManagerException e) {
4107 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
4109 // Delete invalid userdata apps
4110 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
4111 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
4112 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
4113 if (file.isDirectory()) {
4114 FileUtils.deleteContents(file);
4122 private static File getSettingsProblemFile() {
4123 File dataDir = Environment.getDataDirectory();
4124 File systemDir = new File(dataDir, "system");
4125 File fname = new File(systemDir, "uiderrors.txt");
4129 static void reportSettingsProblem(int priority, String msg) {
4130 logCriticalInfo(priority, msg);
4133 static void logCriticalInfo(int priority, String msg) {
4134 Slog.println(priority, TAG, msg);
4135 EventLogTags.writePmCriticalInfo(msg);
4137 File fname = getSettingsProblemFile();
4138 FileOutputStream out = new FileOutputStream(fname, true);
4139 PrintWriter pw = new FastPrintWriter(out);
4140 SimpleDateFormat formatter = new SimpleDateFormat();
4141 String dateString = formatter.format(new Date(System.currentTimeMillis()));
4142 pw.println(dateString + ": " + msg);
4144 FileUtils.setPermissions(
4146 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
4148 } catch (java.io.IOException e) {
4152 private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
4153 PackageParser.Package pkg, File srcFile, int parseFlags)
4154 throws PackageManagerException {
4156 && ps.codePath.equals(srcFile)
4157 && ps.timeStamp == srcFile.lastModified()
4158 && !isCompatSignatureUpdateNeeded(pkg)) {
4159 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
4160 if (ps.signatures.mSignatures != null
4161 && ps.signatures.mSignatures.length != 0
4162 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
4163 // Optimization: reuse the existing cached certificates
4164 // if the package appears to be unchanged.
4165 pkg.mSignatures = ps.signatures.mSignatures;
4166 KeySetManagerService ksms = mSettings.mKeySetManagerService;
4167 synchronized (mPackages) {
4168 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
4173 Slog.w(TAG, "PackageSetting for " + ps.name
4174 + " is missing signatures. Collecting certs again to recover them.");
4176 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
4180 pp.collectCertificates(pkg, parseFlags);
4181 pp.collectManifestDigest(pkg);
4182 } catch (PackageParserException e) {
4183 throw PackageManagerException.from(e);
4188 * Scan a package and return the newly parsed package.
4189 * Returns null in case of errors and the error code is stored in mLastScanError
4191 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
4192 long currentTime, UserHandle user) throws PackageManagerException {
4193 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
4194 parseFlags |= mDefParseFlags;
4195 PackageParser pp = new PackageParser();
4196 pp.setSeparateProcesses(mSeparateProcesses);
4197 pp.setOnlyCoreApps(mOnlyCore);
4198 pp.setDisplayMetrics(mMetrics);
4200 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
4201 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
4204 final PackageParser.Package pkg;
4206 pkg = pp.parsePackage(scanFile, parseFlags);
4207 } catch (PackageParserException e) {
4208 throw PackageManagerException.from(e);
4211 PackageSetting ps = null;
4212 PackageSetting updatedPkg;
4214 synchronized (mPackages) {
4215 // Look to see if we already know about this package.
4216 String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
4217 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
4218 // This package has been renamed to its original name. Let's
4220 ps = mSettings.peekPackageLPr(oldName);
4222 // If there was no original package, see one for the real package name.
4224 ps = mSettings.peekPackageLPr(pkg.packageName);
4226 // Check to see if this package could be hiding/updating a system
4227 // package. Must look for it either under the original or real
4228 // package name depending on our state.
4229 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
4230 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
4232 boolean updatedPkgBetter = false;
4233 // First check if this is a system package that may involve an update
4234 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4235 if (ps != null && !ps.codePath.equals(scanFile)) {
4236 // The path has changed from what was last scanned... check the
4237 // version of the new path against what we have stored to determine
4239 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
4240 if (pkg.mVersionCode < ps.versionCode) {
4241 // The system package has been updated and the code path does not match
4242 // Ignore entry. Skip it.
4243 logCriticalInfo(Log.INFO, "Package " + ps.name + " at " + scanFile
4244 + " ignored: updated version " + ps.versionCode
4245 + " better than this " + pkg.mVersionCode);
4246 if (!updatedPkg.codePath.equals(scanFile)) {
4247 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
4248 + ps.name + " changing from " + updatedPkg.codePathString
4249 + " to " + scanFile);
4250 updatedPkg.codePath = scanFile;
4251 updatedPkg.codePathString = scanFile.toString();
4252 // This is the point at which we know that the system-disk APK
4253 // for this package has moved during a reboot (e.g. due to an OTA),
4254 // so we need to reevaluate it for privilege policy.
4255 if (locationIsPrivileged(scanFile)) {
4256 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
4259 updatedPkg.pkg = pkg;
4260 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
4262 // The current app on the system partition is better than
4263 // what we have updated to on the data partition; switch
4264 // back to the system partition version.
4265 // At this point, its safely assumed that package installation for
4266 // apps in system partition will go through. If not there won't be a working
4267 // version of the app
4269 synchronized (mPackages) {
4270 // Just remove the loaded entries from package lists.
4271 mPackages.remove(ps.name);
4274 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4275 + " reverting from " + ps.codePathString
4276 + ": new version " + pkg.mVersionCode
4277 + " better than installed " + ps.versionCode);
4279 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4280 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4281 getAppDexInstructionSets(ps));
4282 synchronized (mInstallLock) {
4283 args.cleanUpResourcesLI();
4285 synchronized (mPackages) {
4286 mSettings.enableSystemPackageLPw(ps.name);
4288 updatedPkgBetter = true;
4293 if (updatedPkg != null) {
4294 // An updated system app will not have the PARSE_IS_SYSTEM flag set
4296 parseFlags |= PackageParser.PARSE_IS_SYSTEM;
4298 // An updated privileged app will not have the PARSE_IS_PRIVILEGED
4299 // flag set initially
4300 if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
4301 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
4305 // Verify certificates against what was last scanned
4306 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
4309 * A new system app appeared, but we already had a non-system one of the
4310 * same name installed earlier.
4312 boolean shouldHideSystemApp = false;
4313 if (updatedPkg == null && ps != null
4314 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
4316 * Check to make sure the signatures match first. If they don't,
4317 * wipe the installed application and its data.
4319 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
4320 != PackageManager.SIGNATURE_MATCH) {
4321 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
4322 + " signatures don't match existing userdata copy; removing");
4323 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
4327 * If the newly-added system app is an older version than the
4328 * already installed version, hide it. It will be scanned later
4329 * and re-added like an update.
4331 if (pkg.mVersionCode < ps.versionCode) {
4332 shouldHideSystemApp = true;
4333 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
4334 + " but new version " + pkg.mVersionCode + " better than installed "
4335 + ps.versionCode + "; hiding system");
4338 * The newly found system app is a newer version that the
4339 * one previously installed. Simply remove the
4340 * already-installed application and replace it with our own
4341 * while keeping the application data.
4343 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4344 + " reverting from " + ps.codePathString + ": new version "
4345 + pkg.mVersionCode + " better than installed " + ps.versionCode);
4346 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4347 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4348 getAppDexInstructionSets(ps));
4349 synchronized (mInstallLock) {
4350 args.cleanUpResourcesLI();
4356 // The apk is forward locked (not public) if its code and resources
4357 // are kept in different files. (except for app in either system or
4359 // TODO grab this value from PackageSettings
4360 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4361 if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
4362 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
4366 // TODO: extend to support forward-locked splits
4367 String resourcePath = null;
4368 String baseResourcePath = null;
4369 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
4370 if (ps != null && ps.resourcePathString != null) {
4371 resourcePath = ps.resourcePathString;
4372 baseResourcePath = ps.resourcePathString;
4374 // Should not happen at all. Just log an error.
4375 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
4378 resourcePath = pkg.codePath;
4379 baseResourcePath = pkg.baseCodePath;
4382 // Set application objects path explicitly.
4383 pkg.applicationInfo.setCodePath(pkg.codePath);
4384 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
4385 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
4386 pkg.applicationInfo.setResourcePath(resourcePath);
4387 pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
4388 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
4390 // Note that we invoke the following method only if we are about to unpack an application
4391 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
4392 | SCAN_UPDATE_SIGNATURE, currentTime, user);
4395 * If the system app should be overridden by a previously installed
4396 * data, hide the system app now and let the /data/app scan pick it up
4399 if (shouldHideSystemApp) {
4400 synchronized (mPackages) {
4402 * We have to grant systems permissions before we hide, because
4403 * grantPermissions will assume the package update is trying to
4404 * expand its permissions.
4406 grantPermissionsLPw(pkg, true, pkg.packageName);
4407 mSettings.disableSystemPackageLPw(pkg.packageName);
4414 private static String fixProcessName(String defProcessName,
4415 String processName, int uid) {
4416 if (processName == null) {
4417 return defProcessName;
4422 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
4423 throws PackageManagerException {
4424 if (pkgSetting.signatures.mSignatures != null) {
4425 // Already existing package. Make sure signatures match
4426 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
4427 == PackageManager.SIGNATURE_MATCH;
4429 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
4430 == PackageManager.SIGNATURE_MATCH;
4433 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
4434 + pkg.packageName + " signatures do not match the "
4435 + "previously installed version; ignoring!");
4439 // Check for shared user signatures
4440 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
4441 // Already existing package. Make sure signatures match
4442 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4443 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
4445 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
4446 == PackageManager.SIGNATURE_MATCH;
4449 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
4450 "Package " + pkg.packageName
4451 + " has no signatures that match those in shared user "
4452 + pkgSetting.sharedUser.name + "; ignoring!");
4458 * Enforces that only the system UID or root's UID can call a method exposed
4461 * @param message used as message if SecurityException is thrown
4462 * @throws SecurityException if the caller is not system or root
4464 private static final void enforceSystemOrRoot(String message) {
4465 final int uid = Binder.getCallingUid();
4466 if (uid != Process.SYSTEM_UID && uid != 0) {
4467 throw new SecurityException(message);
4472 public void performBootDexOpt() {
4473 enforceSystemOrRoot("Only the system can request dexopt be performed");
4475 final HashSet<PackageParser.Package> pkgs;
4476 synchronized (mPackages) {
4477 pkgs = mDeferredDexOpt;
4478 mDeferredDexOpt = null;
4482 // Sort apps by importance for dexopt ordering. Important apps are given more priority
4483 // in case the device runs out of space.
4484 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
4485 // Give priority to core apps.
4486 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4487 PackageParser.Package pkg = it.next();
4490 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
4492 sortedPkgs.add(pkg);
4496 // Give priority to system apps that listen for pre boot complete.
4497 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
4498 HashSet<String> pkgNames = getPackageNamesForIntent(intent);
4499 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4500 PackageParser.Package pkg = it.next();
4501 if (pkgNames.contains(pkg.packageName)) {
4503 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
4505 sortedPkgs.add(pkg);
4509 // Give priority to system apps.
4510 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4511 PackageParser.Package pkg = it.next();
4512 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4514 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
4516 sortedPkgs.add(pkg);
4520 // Give priority to updated system apps.
4521 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4522 PackageParser.Package pkg = it.next();
4523 if (isUpdatedSystemApp(pkg)) {
4525 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
4527 sortedPkgs.add(pkg);
4531 // Give priority to apps that listen for boot complete.
4532 intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
4533 pkgNames = getPackageNamesForIntent(intent);
4534 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4535 PackageParser.Package pkg = it.next();
4536 if (pkgNames.contains(pkg.packageName)) {
4538 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
4540 sortedPkgs.add(pkg);
4544 // Filter out packages that aren't recently used.
4545 filterRecentlyUsedApps(pkgs);
4546 // Add all remaining apps.
4547 for (PackageParser.Package pkg : pkgs) {
4549 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
4551 sortedPkgs.add(pkg);
4555 int total = sortedPkgs.size();
4556 File dataDir = Environment.getDataDirectory();
4557 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
4558 if (lowThreshold == 0) {
4559 throw new IllegalStateException("Invalid low memory threshold");
4561 for (PackageParser.Package pkg : sortedPkgs) {
4562 long usableSpace = dataDir.getUsableSpace();
4563 if (usableSpace < lowThreshold) {
4564 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
4567 performBootDexOpt(pkg, ++i, total);
4572 private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) {
4573 // Filter out packages that aren't recently used.
4575 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
4576 // should do a full dexopt.
4577 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
4578 // TODO: add a property to control this?
4579 long dexOptLRUThresholdInMinutes;
4581 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
4583 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
4585 long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
4587 int total = pkgs.size();
4589 long now = System.currentTimeMillis();
4590 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
4591 PackageParser.Package pkg = i.next();
4592 long then = pkg.mLastPackageUsageTimeInMills;
4593 if (then + dexOptLRUThresholdInMills < now) {
4595 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
4596 ((then == 0) ? "never" : new Date(then)));
4603 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
4608 private HashSet<String> getPackageNamesForIntent(Intent intent) {
4609 List<ResolveInfo> ris = null;
4611 ris = AppGlobals.getPackageManager().queryIntentReceivers(
4612 intent, null, 0, UserHandle.USER_OWNER);
4613 } catch (RemoteException e) {
4615 HashSet<String> pkgNames = new HashSet<String>();
4617 for (ResolveInfo ri : ris) {
4618 pkgNames.add(ri.activityInfo.packageName);
4624 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
4626 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
4628 if (!isFirstBoot()) {
4630 ActivityManagerNative.getDefault().showBootMessage(
4631 mContext.getResources().getString(R.string.android_upgrading_apk,
4632 curr, total), true);
4633 } catch (RemoteException e) {
4636 PackageParser.Package p = pkg;
4637 synchronized (mInstallLock) {
4638 performDexOptLI(p, null /* instruction sets */, false /* force dex */,
4639 false /* defer */, true /* include dependencies */);
4644 public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
4645 return performDexOpt(packageName, instructionSet, false);
4648 private static String getPrimaryInstructionSet(ApplicationInfo info) {
4649 if (info.primaryCpuAbi == null) {
4650 return getPreferredInstructionSet();
4653 return VMRuntime.getInstructionSet(info.primaryCpuAbi);
4656 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
4657 boolean dexopt = mLazyDexOpt || backgroundDexopt;
4658 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt
4659 if (!dexopt && !updateUsage) {
4660 // We aren't going to dexopt or update usage, so bail early.
4663 PackageParser.Package p;
4664 final String targetInstructionSet;
4665 synchronized (mPackages) {
4666 p = mPackages.get(packageName);
4671 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
4673 mPackageUsage.write(false);
4675 // We aren't going to dexopt, so bail early.
4679 targetInstructionSet = instructionSet != null ? instructionSet :
4680 getPrimaryInstructionSet(p.applicationInfo);
4681 if (p.mDexOptPerformed.contains(targetInstructionSet)) {
4686 synchronized (mInstallLock) {
4687 final String[] instructionSets = new String[] { targetInstructionSet };
4688 return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
4689 true /* include dependencies */) == DEX_OPT_PERFORMED;
4693 public HashSet<String> getPackagesThatNeedDexOpt() {
4694 HashSet<String> pkgs = null;
4695 synchronized (mPackages) {
4696 for (PackageParser.Package p : mPackages.values()) {
4698 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
4700 if (!p.mDexOptPerformed.isEmpty()) {
4704 pkgs = new HashSet<String>();
4706 pkgs.add(p.packageName);
4712 public void shutdown() {
4713 mPackageUsage.write(true);
4716 private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
4717 boolean forceDex, boolean defer, HashSet<String> done) {
4718 for (int i=0; i<libs.size(); i++) {
4719 PackageParser.Package libPkg;
4721 synchronized (mPackages) {
4722 libName = libs.get(i);
4723 SharedLibraryEntry lib = mSharedLibraries.get(libName);
4724 if (lib != null && lib.apk != null) {
4725 libPkg = mPackages.get(lib.apk);
4730 if (libPkg != null && !done.contains(libName)) {
4731 performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
4736 static final int DEX_OPT_SKIPPED = 0;
4737 static final int DEX_OPT_PERFORMED = 1;
4738 static final int DEX_OPT_DEFERRED = 2;
4739 static final int DEX_OPT_FAILED = -1;
4741 private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
4742 boolean forceDex, boolean defer, HashSet<String> done) {
4743 final String[] instructionSets = targetInstructionSets != null ?
4744 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
4747 done.add(pkg.packageName);
4748 if (pkg.usesLibraries != null) {
4749 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
4751 if (pkg.usesOptionalLibraries != null) {
4752 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
4756 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
4757 return DEX_OPT_SKIPPED;
4760 final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
4762 final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
4763 boolean performedDexOpt = false;
4764 // There are three basic cases here:
4765 // 1.) we need to dexopt, either because we are forced or it is needed
4766 // 2.) we are defering a needed dexopt
4767 // 3.) we are skipping an unneeded dexopt
4768 final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
4769 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4770 if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
4774 for (String path : paths) {
4776 // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
4777 // patckage or the one we find does not match the image checksum (i.e. it was
4778 // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
4779 // odex file and it matches the checksum of the image but not its base address,
4780 // meaning we need to move it.
4781 final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
4782 pkg.packageName, dexCodeInstructionSet, defer);
4783 if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
4784 Log.i(TAG, "Running dexopt on: " + path + " pkg="
4785 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
4786 + " vmSafeMode=" + vmSafeMode);
4787 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4788 final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
4789 pkg.packageName, dexCodeInstructionSet, vmSafeMode);
4792 // Don't bother running dexopt again if we failed, it will probably
4793 // just result in an error again. Also, don't bother dexopting for other
4795 return DEX_OPT_FAILED;
4798 performedDexOpt = true;
4799 } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
4800 Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
4801 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4802 final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
4803 pkg.packageName, dexCodeInstructionSet);
4806 // Don't bother running patchoat again if we failed, it will probably
4807 // just result in an error again. Also, don't bother dexopting for other
4809 return DEX_OPT_FAILED;
4812 performedDexOpt = true;
4815 // We're deciding to defer a needed dexopt. Don't bother dexopting for other
4816 // paths and instruction sets. We'll deal with them all together when we process
4817 // our list of deferred dexopts.
4818 if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
4819 if (mDeferredDexOpt == null) {
4820 mDeferredDexOpt = new HashSet<PackageParser.Package>();
4822 mDeferredDexOpt.add(pkg);
4823 return DEX_OPT_DEFERRED;
4825 } catch (FileNotFoundException e) {
4826 Slog.w(TAG, "Apk not found for dexopt: " + path);
4827 return DEX_OPT_FAILED;
4828 } catch (IOException e) {
4829 Slog.w(TAG, "IOException reading apk: " + path, e);
4830 return DEX_OPT_FAILED;
4831 } catch (StaleDexCacheError e) {
4832 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
4833 return DEX_OPT_FAILED;
4834 } catch (Exception e) {
4835 Slog.w(TAG, "Exception when doing dexopt : ", e);
4836 return DEX_OPT_FAILED;
4840 // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
4841 // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
4842 // it isn't required. We therefore mark that this package doesn't need dexopt unless
4843 // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
4845 pkg.mDexOptPerformed.add(dexCodeInstructionSet);
4848 // If we've gotten here, we're sure that no error occurred and that we haven't
4849 // deferred dex-opt. We've either dex-opted one more paths or instruction sets or
4850 // we've skipped all of them because they are up to date. In both cases this
4851 // package doesn't need dexopt any longer.
4852 return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
4855 private static String[] getAppDexInstructionSets(ApplicationInfo info) {
4856 if (info.primaryCpuAbi != null) {
4857 if (info.secondaryCpuAbi != null) {
4858 return new String[] {
4859 VMRuntime.getInstructionSet(info.primaryCpuAbi),
4860 VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
4862 return new String[] {
4863 VMRuntime.getInstructionSet(info.primaryCpuAbi) };
4867 return new String[] { getPreferredInstructionSet() };
4870 private static String[] getAppDexInstructionSets(PackageSetting ps) {
4871 if (ps.primaryCpuAbiString != null) {
4872 if (ps.secondaryCpuAbiString != null) {
4873 return new String[] {
4874 VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
4875 VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
4877 return new String[] {
4878 VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
4882 return new String[] { getPreferredInstructionSet() };
4885 private static String getPreferredInstructionSet() {
4886 if (sPreferredInstructionSet == null) {
4887 sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
4890 return sPreferredInstructionSet;
4893 private static List<String> getAllInstructionSets() {
4894 final String[] allAbis = Build.SUPPORTED_ABIS;
4895 final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
4897 for (String abi : allAbis) {
4898 final String instructionSet = VMRuntime.getInstructionSet(abi);
4899 if (!allInstructionSets.contains(instructionSet)) {
4900 allInstructionSets.add(instructionSet);
4904 return allInstructionSets;
4908 * Returns the instruction set that should be used to compile dex code. In the presence of
4909 * a native bridge this might be different than the one shared libraries use.
4911 private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
4912 String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
4913 return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
4916 private static String[] getDexCodeInstructionSets(String[] instructionSets) {
4917 HashSet<String> dexCodeInstructionSets = new HashSet<String>(instructionSets.length);
4918 for (String instructionSet : instructionSets) {
4919 dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
4921 return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
4925 * Returns deduplicated list of supported instructions for dex code.
4927 public static String[] getAllDexCodeInstructionSets() {
4928 String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
4929 for (int i = 0; i < supportedInstructionSets.length; i++) {
4930 String abi = Build.SUPPORTED_ABIS[i];
4931 supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
4933 return getDexCodeInstructionSets(supportedInstructionSets);
4937 public void forceDexOpt(String packageName) {
4938 enforceSystemOrRoot("forceDexOpt");
4940 PackageParser.Package pkg;
4941 synchronized (mPackages) {
4942 pkg = mPackages.get(packageName);
4944 throw new IllegalArgumentException("Missing package: " + packageName);
4948 synchronized (mInstallLock) {
4949 final String[] instructionSets = new String[] {
4950 getPrimaryInstructionSet(pkg.applicationInfo) };
4951 final int res = performDexOptLI(pkg, instructionSets, true, false, true);
4952 if (res != DEX_OPT_PERFORMED) {
4953 throw new IllegalStateException("Failed to dexopt: " + res);
4958 private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets,
4959 boolean forceDex, boolean defer, boolean inclDependencies) {
4960 HashSet<String> done;
4961 if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
4962 done = new HashSet<String>();
4963 done.add(pkg.packageName);
4967 return performDexOptLI(pkg, instructionSets, forceDex, defer, done);
4970 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
4971 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
4972 Slog.w(TAG, "Unable to update from " + oldPkg.name
4973 + " to " + newPkg.packageName
4974 + ": old package not in system partition");
4976 } else if (mPackages.get(oldPkg.name) != null) {
4977 Slog.w(TAG, "Unable to update from " + oldPkg.name
4978 + " to " + newPkg.packageName
4979 + ": old package still exists");
4985 File getDataPathForUser(int userId) {
4986 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
4989 private File getDataPathForPackage(String packageName, int userId) {
4991 * Until we fully support multiple users, return the directory we
4992 * previously would have. The PackageManagerTests will need to be
4993 * revised when this is changed back..
4996 return new File(mAppDataDir, packageName);
4998 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
4999 + File.separator + packageName);
5003 private int createDataDirsLI(String packageName, int uid, String seinfo) {
5004 int[] users = sUserManager.getUserIds();
5005 int res = mInstaller.install(packageName, uid, uid, seinfo);
5009 for (int user : users) {
5011 res = mInstaller.createUserData(packageName,
5012 UserHandle.getUid(user, uid), user, seinfo);
5021 private int removeDataDirsLI(String packageName) {
5022 int[] users = sUserManager.getUserIds();
5024 for (int user : users) {
5025 int resInner = mInstaller.remove(packageName, user);
5034 private int deleteCodeCacheDirsLI(String packageName) {
5035 int[] users = sUserManager.getUserIds();
5037 for (int user : users) {
5038 int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
5046 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
5047 PackageParser.Package changingLib) {
5048 if (file.path != null) {
5049 usesLibraryFiles.add(file.path);
5052 PackageParser.Package p = mPackages.get(file.apk);
5053 if (changingLib != null && changingLib.packageName.equals(file.apk)) {
5054 // If we are doing this while in the middle of updating a library apk,
5055 // then we need to make sure to use that new apk for determining the
5056 // dependencies here. (We haven't yet finished committing the new apk
5057 // to the package manager state.)
5058 if (p == null || p.packageName.equals(changingLib.packageName)) {
5063 usesLibraryFiles.addAll(p.getAllCodePaths());
5067 private void updateSharedLibrariesLPw(PackageParser.Package pkg,
5068 PackageParser.Package changingLib) throws PackageManagerException {
5069 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
5070 final ArraySet<String> usesLibraryFiles = new ArraySet<>();
5071 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
5072 for (int i=0; i<N; i++) {
5073 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
5075 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
5076 "Package " + pkg.packageName + " requires unavailable shared library "
5077 + pkg.usesLibraries.get(i) + "; failing!");
5079 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5081 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
5082 for (int i=0; i<N; i++) {
5083 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
5085 Slog.w(TAG, "Package " + pkg.packageName
5086 + " desires unavailable shared library "
5087 + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
5089 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5092 N = usesLibraryFiles.size();
5094 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
5096 pkg.usesLibraryFiles = null;
5101 private static boolean hasString(List<String> list, List<String> which) {
5105 for (int i=list.size()-1; i>=0; i--) {
5106 for (int j=which.size()-1; j>=0; j--) {
5107 if (which.get(j).equals(list.get(i))) {
5115 private void updateAllSharedLibrariesLPw() {
5116 for (PackageParser.Package pkg : mPackages.values()) {
5118 updateSharedLibrariesLPw(pkg, null);
5119 } catch (PackageManagerException e) {
5120 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5125 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
5126 PackageParser.Package changingPkg) {
5127 ArrayList<PackageParser.Package> res = null;
5128 for (PackageParser.Package pkg : mPackages.values()) {
5129 if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
5130 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
5132 res = new ArrayList<PackageParser.Package>();
5136 updateSharedLibrariesLPw(pkg, changingPkg);
5137 } catch (PackageManagerException e) {
5138 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5146 * Derive the value of the {@code cpuAbiOverride} based on the provided
5147 * value and an optional stored value from the package settings.
5149 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
5150 String cpuAbiOverride = null;
5152 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
5153 cpuAbiOverride = null;
5154 } else if (abiOverride != null) {
5155 cpuAbiOverride = abiOverride;
5156 } else if (settings != null) {
5157 cpuAbiOverride = settings.cpuAbiOverrideString;
5160 return cpuAbiOverride;
5163 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
5164 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5165 boolean success = false;
5167 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
5172 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5173 removeDataDirsLI(pkg.packageName);
5178 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
5179 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5180 final File scanFile = new File(pkg.codePath);
5181 if (pkg.applicationInfo.getCodePath() == null ||
5182 pkg.applicationInfo.getResourcePath() == null) {
5183 // Bail out. The resource and code paths haven't been set.
5184 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
5185 "Code and resource paths haven't been set correctly");
5188 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5189 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
5191 // Only allow system apps to be flagged as core apps.
5192 pkg.coreApp = false;
5195 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
5196 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
5199 if (mCustomResolverComponentName != null &&
5200 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
5201 setUpCustomResolverActivity(pkg);
5204 if (pkg.packageName.equals("android")) {
5205 synchronized (mPackages) {
5206 if (mAndroidApplication != null) {
5207 Slog.w(TAG, "*************************************************");
5208 Slog.w(TAG, "Core android package being redefined. Skipping.");
5209 Slog.w(TAG, " file=" + scanFile);
5210 Slog.w(TAG, "*************************************************");
5211 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5212 "Core android package being redefined. Skipping.");
5215 // Set up information for our fall-back user intent resolution activity.
5216 mPlatformPackage = pkg;
5217 pkg.mVersionCode = mSdkVersion;
5218 mAndroidApplication = pkg.applicationInfo;
5220 if (!mResolverReplaced) {
5221 mResolveActivity.applicationInfo = mAndroidApplication;
5222 mResolveActivity.name = ResolverActivity.class.getName();
5223 mResolveActivity.packageName = mAndroidApplication.packageName;
5224 mResolveActivity.processName = "system:ui";
5225 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5226 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
5227 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
5228 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
5229 mResolveActivity.exported = true;
5230 mResolveActivity.enabled = true;
5231 mResolveInfo.activityInfo = mResolveActivity;
5232 mResolveInfo.priority = 0;
5233 mResolveInfo.preferredOrder = 0;
5234 mResolveInfo.match = 0;
5235 mResolveComponentName = new ComponentName(
5236 mAndroidApplication.packageName, mResolveActivity.name);
5241 if (DEBUG_PACKAGE_SCANNING) {
5242 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5243 Log.d(TAG, "Scanning package " + pkg.packageName);
5246 if (mPackages.containsKey(pkg.packageName)
5247 || mSharedLibraries.containsKey(pkg.packageName)) {
5248 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5249 "Application package " + pkg.packageName
5250 + " already installed. Skipping duplicate.");
5253 // Initialize package source and resource directories
5254 File destCodeFile = new File(pkg.applicationInfo.getCodePath());
5255 File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
5257 SharedUserSetting suid = null;
5258 PackageSetting pkgSetting = null;
5260 if (!isSystemApp(pkg)) {
5261 // Only system apps can use these features.
5262 pkg.mOriginalPackages = null;
5263 pkg.mRealPackage = null;
5264 pkg.mAdoptPermissions = null;
5268 synchronized (mPackages) {
5269 if (pkg.mSharedUserId != null) {
5270 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
5272 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5273 "Creating application package " + pkg.packageName
5274 + " for shared user failed");
5276 if (DEBUG_PACKAGE_SCANNING) {
5277 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5278 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
5279 + "): packages=" + suid.packages);
5283 // Check if we are renaming from an original package name.
5284 PackageSetting origPackage = null;
5285 String realName = null;
5286 if (pkg.mOriginalPackages != null) {
5287 // This package may need to be renamed to a previously
5288 // installed name. Let's check on that...
5289 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
5290 if (pkg.mOriginalPackages.contains(renamed)) {
5291 // This package had originally been installed as the
5292 // original name, and we have already taken care of
5293 // transitioning to the new one. Just update the new
5294 // one to continue using the old name.
5295 realName = pkg.mRealPackage;
5296 if (!pkg.packageName.equals(renamed)) {
5297 // Callers into this function may have already taken
5298 // care of renaming the package; only do it here if
5299 // it is not already done.
5300 pkg.setPackageName(renamed);
5304 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
5305 if ((origPackage = mSettings.peekPackageLPr(
5306 pkg.mOriginalPackages.get(i))) != null) {
5307 // We do have the package already installed under its
5308 // original name... should we use it?
5309 if (!verifyPackageUpdateLPr(origPackage, pkg)) {
5310 // New package is not compatible with original.
5313 } else if (origPackage.sharedUser != null) {
5314 // Make sure uid is compatible between packages.
5315 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
5316 Slog.w(TAG, "Unable to migrate data from " + origPackage.name
5317 + " to " + pkg.packageName + ": old uid "
5318 + origPackage.sharedUser.name
5319 + " differs from " + pkg.mSharedUserId);
5324 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
5325 + pkg.packageName + " to old name " + origPackage.name);
5333 if (mTransferedPackages.contains(pkg.packageName)) {
5334 Slog.w(TAG, "Package " + pkg.packageName
5335 + " was transferred to another, but its .apk remains");
5338 // Just create the setting, don't add it yet. For already existing packages
5339 // the PkgSetting exists already and doesn't have to be created.
5340 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
5341 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
5342 pkg.applicationInfo.primaryCpuAbi,
5343 pkg.applicationInfo.secondaryCpuAbi,
5344 pkg.applicationInfo.flags, user, false);
5345 if (pkgSetting == null) {
5346 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5347 "Creating application package " + pkg.packageName + " failed");
5350 if (pkgSetting.origPackage != null) {
5351 // If we are first transitioning from an original package,
5352 // fix up the new package's name now. We need to do this after
5353 // looking up the package under its new name, so getPackageLP
5354 // can take care of fiddling things correctly.
5355 pkg.setPackageName(origPackage.name);
5357 // File a report about this.
5358 String msg = "New package " + pkgSetting.realName
5359 + " renamed to replace old package " + pkgSetting.name;
5360 reportSettingsProblem(Log.WARN, msg);
5362 // Make a note of it.
5363 mTransferedPackages.add(origPackage.name);
5365 // No longer need to retain this.
5366 pkgSetting.origPackage = null;
5369 if (realName != null) {
5370 // Make a note of it.
5371 mTransferedPackages.add(pkg.packageName);
5374 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
5375 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
5378 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5379 // Check all shared libraries and map to their actual file path.
5380 // We only do this here for apps not on a system dir, because those
5381 // are the only ones that can fail an install due to this. We
5382 // will take care of the system apps by updating all of their
5383 // library paths after the scan is done.
5384 updateSharedLibrariesLPw(pkg, null);
5387 if (mFoundPolicyFile) {
5388 SELinuxMMAC.assignSeinfoValue(pkg);
5391 pkg.applicationInfo.uid = pkgSetting.appId;
5392 pkg.mExtras = pkgSetting;
5393 if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
5395 verifySignaturesLP(pkgSetting, pkg);
5396 } catch (PackageManagerException e) {
5397 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5400 // The signature has changed, but this package is in the system
5401 // image... let's recover!
5402 pkgSetting.signatures.mSignatures = pkg.mSignatures;
5403 // However... if this package is part of a shared user, but it
5404 // doesn't match the signature of the shared user, let's fail.
5405 // What this means is that you can't change the signatures
5406 // associated with an overall shared user, which doesn't seem all
5407 // that unreasonable.
5408 if (pkgSetting.sharedUser != null) {
5409 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5410 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
5411 throw new PackageManagerException(
5412 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
5413 "Signature mismatch for shared user : "
5414 + pkgSetting.sharedUser);
5417 // File a report about this.
5418 String msg = "System package " + pkg.packageName
5419 + " signature changed; retaining data.";
5420 reportSettingsProblem(Log.WARN, msg);
5423 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
5424 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5425 + pkg.packageName + " upgrade keys do not match the "
5426 + "previously installed version");
5428 // signatures may have changed as result of upgrade
5429 pkgSetting.signatures.mSignatures = pkg.mSignatures;
5432 // Verify that this new package doesn't have any content providers
5433 // that conflict with existing packages. Only do this if the
5434 // package isn't already installed, since we don't want to break
5435 // things that are installed.
5436 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
5437 final int N = pkg.providers.size();
5439 for (i=0; i<N; i++) {
5440 PackageParser.Provider p = pkg.providers.get(i);
5441 if (p.info.authority != null) {
5442 String names[] = p.info.authority.split(";");
5443 for (int j = 0; j < names.length; j++) {
5444 if (mProvidersByAuthority.containsKey(names[j])) {
5445 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
5446 final String otherPackageName =
5447 ((other != null && other.getComponentName() != null) ?
5448 other.getComponentName().getPackageName() : "?");
5449 throw new PackageManagerException(
5450 INSTALL_FAILED_CONFLICTING_PROVIDER,
5451 "Can't install because provider name " + names[j]
5452 + " (in package " + pkg.applicationInfo.packageName
5453 + ") is already used by " + otherPackageName);
5460 if (pkg.mAdoptPermissions != null) {
5461 // This package wants to adopt ownership of permissions from
5463 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
5464 final String origName = pkg.mAdoptPermissions.get(i);
5465 final PackageSetting orig = mSettings.peekPackageLPr(origName);
5467 if (verifyPackageUpdateLPr(orig, pkg)) {
5468 Slog.i(TAG, "Adopting permissions from " + origName + " to "
5470 mSettings.transferPermissionsLPw(origName, pkg.packageName);
5477 final String pkgName = pkg.packageName;
5479 final long scanFileTime = scanFile.lastModified();
5480 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
5481 pkg.applicationInfo.processName = fixProcessName(
5482 pkg.applicationInfo.packageName,
5483 pkg.applicationInfo.processName,
5484 pkg.applicationInfo.uid);
5487 if (mPlatformPackage == pkg) {
5488 // The system package is special.
5489 dataPath = new File(Environment.getDataDirectory(), "system");
5491 pkg.applicationInfo.dataDir = dataPath.getPath();
5494 // This is a normal package, need to make its data directory.
5495 dataPath = getDataPathForPackage(pkg.packageName, 0);
5497 boolean uidError = false;
5498 if (dataPath.exists()) {
5501 StructStat stat = Os.stat(dataPath.getPath());
5502 currentUid = stat.st_uid;
5503 } catch (ErrnoException e) {
5504 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
5507 // If we have mismatched owners for the data path, we have a problem.
5508 if (currentUid != pkg.applicationInfo.uid) {
5509 boolean recovered = false;
5510 if (currentUid == 0) {
5511 // The directory somehow became owned by root. Wow.
5512 // This is probably because the system was stopped while
5513 // installd was in the middle of messing with its libs
5514 // directory. Ask installd to fix that.
5515 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
5516 pkg.applicationInfo.uid);
5519 String msg = "Package " + pkg.packageName
5520 + " unexpectedly changed to uid 0; recovered to " +
5521 + pkg.applicationInfo.uid;
5522 reportSettingsProblem(Log.WARN, msg);
5525 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5526 || (scanFlags&SCAN_BOOTING) != 0)) {
5527 // If this is a system app, we can at least delete its
5528 // current data so the application will still work.
5529 int ret = removeDataDirsLI(pkgName);
5531 // TODO: Kill the processes first
5533 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5534 ? "System package " : "Third party package ";
5535 String msg = prefix + pkg.packageName
5536 + " has changed from uid: "
5537 + currentUid + " to "
5538 + pkg.applicationInfo.uid + "; old data erased";
5539 reportSettingsProblem(Log.WARN, msg);
5542 // And now re-install the app.
5543 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5544 pkg.applicationInfo.seinfo);
5546 // Ack should not happen!
5547 msg = prefix + pkg.packageName
5548 + " could not have data directory re-created after delete.";
5549 reportSettingsProblem(Log.WARN, msg);
5550 throw new PackageManagerException(
5551 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
5555 mHasSystemUidErrors = true;
5557 } else if (!recovered) {
5558 // If we allow this install to proceed, we will be broken.
5560 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
5564 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
5565 + pkg.applicationInfo.uid + "/fs_"
5567 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
5568 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
5569 String msg = "Package " + pkg.packageName
5570 + " has mismatched uid: "
5571 + currentUid + " on disk, "
5572 + pkg.applicationInfo.uid + " in settings";
5574 synchronized (mPackages) {
5575 mSettings.mReadMessages.append(msg);
5576 mSettings.mReadMessages.append('\n');
5578 if (!pkgSetting.uidError) {
5579 reportSettingsProblem(Log.ERROR, msg);
5584 pkg.applicationInfo.dataDir = dataPath.getPath();
5585 if (mShouldRestoreconData) {
5586 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
5587 mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
5588 pkg.applicationInfo.uid);
5591 if (DEBUG_PACKAGE_SCANNING) {
5592 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5593 Log.v(TAG, "Want this data dir: " + dataPath);
5595 //invoke installer to do the actual installation
5596 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5597 pkg.applicationInfo.seinfo);
5599 // Error from installer
5600 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5601 "Unable to create data dirs [errorCode=" + ret + "]");
5604 if (dataPath.exists()) {
5605 pkg.applicationInfo.dataDir = dataPath.getPath();
5607 Slog.w(TAG, "Unable to create data directory: " + dataPath);
5608 pkg.applicationInfo.dataDir = null;
5612 pkgSetting.uidError = uidError;
5615 final String path = scanFile.getPath();
5616 final String codePath = pkg.applicationInfo.getCodePath();
5617 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
5618 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
5619 setBundledAppAbisAndRoots(pkg, pkgSetting);
5621 // If we haven't found any native libraries for the app, check if it has
5622 // renderscript code. We'll need to force the app to 32 bit if it has
5623 // renderscript bitcode.
5624 if (pkg.applicationInfo.primaryCpuAbi == null
5625 && pkg.applicationInfo.secondaryCpuAbi == null
5626 && Build.SUPPORTED_64_BIT_ABIS.length > 0) {
5627 NativeLibraryHelper.Handle handle = null;
5629 handle = NativeLibraryHelper.Handle.create(scanFile);
5630 if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5631 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
5633 } catch (IOException ioe) {
5634 Slog.w(TAG, "Error scanning system app : " + ioe);
5636 IoUtils.closeQuietly(handle);
5640 setNativeLibraryPaths(pkg);
5642 // TODO: We can probably be smarter about this stuff. For installed apps,
5643 // we can calculate this information at install time once and for all. For
5644 // system apps, we can probably assume that this information doesn't change
5645 // after the first boot scan. As things stand, we do lots of unnecessary work.
5647 // Give ourselves some initial paths; we'll come back for another
5648 // pass once we've determined ABI below.
5649 setNativeLibraryPaths(pkg);
5651 final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
5652 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
5653 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
5655 NativeLibraryHelper.Handle handle = null;
5657 handle = NativeLibraryHelper.Handle.create(scanFile);
5658 // TODO(multiArch): This can be null for apps that didn't go through the
5659 // usual installation process. We can calculate it again, like we
5660 // do during install time.
5662 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
5664 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
5666 // Null out the abis so that they can be recalculated.
5667 pkg.applicationInfo.primaryCpuAbi = null;
5668 pkg.applicationInfo.secondaryCpuAbi = null;
5669 if (isMultiArch(pkg.applicationInfo)) {
5670 // Warn if we've set an abiOverride for multi-lib packages..
5671 // By definition, we need to copy both 32 and 64 bit libraries for
5673 if (pkg.cpuAbiOverride != null
5674 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
5675 Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
5678 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
5679 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
5680 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
5682 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
5684 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5685 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
5686 useIsaSpecificSubdirs);
5690 maybeThrowExceptionForMultiArchCopy(
5691 "Error unpackaging 32 bit native libs for multiarch app.", abi32);
5693 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
5695 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
5697 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5698 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
5699 useIsaSpecificSubdirs);
5703 maybeThrowExceptionForMultiArchCopy(
5704 "Error unpackaging 64 bit native libs for multiarch app.", abi64);
5707 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
5711 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
5713 pkg.applicationInfo.secondaryCpuAbi = abi;
5715 pkg.applicationInfo.primaryCpuAbi = abi;
5719 String[] abiList = (cpuAbiOverride != null) ?
5720 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
5722 // Enable gross and lame hacks for apps that are built with old
5723 // SDK tools. We must scan their APKs for renderscript bitcode and
5724 // not launch them if it's present. Don't bother checking on devices
5725 // that don't have 64 bit support.
5726 boolean needsRenderScriptOverride = false;
5727 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
5728 NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5729 abiList = Build.SUPPORTED_32_BIT_ABIS;
5730 needsRenderScriptOverride = true;
5735 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
5737 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5738 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
5741 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
5742 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5743 "Error unpackaging native libs for app, errorCode=" + copyRet);
5747 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
5748 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
5749 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
5750 } else if (needsRenderScriptOverride) {
5751 pkg.applicationInfo.primaryCpuAbi = abiList[0];
5754 } catch (IOException ioe) {
5755 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
5757 IoUtils.closeQuietly(handle);
5760 // Now that we've calculated the ABIs and determined if it's an internal app,
5761 // we will go ahead and populate the nativeLibraryPath.
5762 setNativeLibraryPaths(pkg);
5764 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
5765 final int[] userIds = sUserManager.getUserIds();
5766 synchronized (mInstallLock) {
5767 // Create a native library symlink only if we have native libraries
5768 // and if the native libraries are 32 bit libraries. We do not provide
5769 // this symlink for 64 bit libraries.
5770 if (pkg.applicationInfo.primaryCpuAbi != null &&
5771 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
5772 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
5773 for (int userId : userIds) {
5774 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
5775 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5776 "Failed linking native library dir (user=" + userId + ")");
5783 // This is a special case for the "system" package, where the ABI is
5784 // dictated by the zygote configuration (and init.rc). We should keep track
5785 // of this ABI so that we can deal with "normal" applications that run under
5786 // the same UID correctly.
5787 if (mPlatformPackage == pkg) {
5788 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
5789 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
5792 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
5793 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
5794 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
5795 // Copy the derived override back to the parsed package, so that we can
5796 // update the package settings accordingly.
5797 pkg.cpuAbiOverride = cpuAbiOverride;
5799 if (DEBUG_ABI_SELECTION) {
5800 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
5801 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
5802 + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
5805 // Push the derived path down into PackageSettings so we know what to
5806 // clean up at uninstall time.
5807 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
5809 if (DEBUG_ABI_SELECTION) {
5810 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
5811 " primary=" + pkg.applicationInfo.primaryCpuAbi +
5812 " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
5815 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
5816 // We don't do this here during boot because we can do it all
5817 // at once after scanning all existing packages.
5819 // We also do this *before* we perform dexopt on this package, so that
5820 // we can avoid redundant dexopts, and also to make sure we've got the
5821 // code and package path correct.
5822 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
5823 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
5826 if ((scanFlags & SCAN_NO_DEX) == 0) {
5827 if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
5828 (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5829 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
5833 if (mFactoryTest && pkg.requestedPermissions.contains(
5834 android.Manifest.permission.FACTORY_TEST)) {
5835 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
5838 ArrayList<PackageParser.Package> clientLibPkgs = null;
5841 synchronized (mPackages) {
5842 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5843 // Only system apps can add new shared libraries.
5844 if (pkg.libraryNames != null) {
5845 for (int i=0; i<pkg.libraryNames.size(); i++) {
5846 String name = pkg.libraryNames.get(i);
5847 boolean allowed = false;
5848 if (isUpdatedSystemApp(pkg)) {
5849 // New library entries can only be added through the
5850 // system image. This is important to get rid of a lot
5851 // of nasty edge cases: for example if we allowed a non-
5852 // system update of the app to add a library, then uninstalling
5853 // the update would make the library go away, and assumptions
5854 // we made such as through app install filtering would now
5855 // have allowed apps on the device which aren't compatible
5856 // with it. Better to just have the restriction here, be
5857 // conservative, and create many fewer cases that can negatively
5858 // impact the user experience.
5859 final PackageSetting sysPs = mSettings
5860 .getDisabledSystemPkgLPr(pkg.packageName);
5861 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
5862 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
5863 if (name.equals(sysPs.pkg.libraryNames.get(j))) {
5874 if (!mSharedLibraries.containsKey(name)) {
5875 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
5876 } else if (!name.equals(pkg.packageName)) {
5877 Slog.w(TAG, "Package " + pkg.packageName + " library "
5878 + name + " already exists; skipping");
5881 Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
5882 + name + " that is not declared on system image; skipping");
5885 if ((scanFlags&SCAN_BOOTING) == 0) {
5886 // If we are not booting, we need to update any applications
5887 // that are clients of our shared library. If we are booting,
5888 // this will all be done once the scan is complete.
5889 clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
5895 // We also need to dexopt any apps that are dependent on this library. Note that
5896 // if these fail, we should abort the install since installing the library will
5897 // result in some apps being broken.
5898 if (clientLibPkgs != null) {
5899 if ((scanFlags & SCAN_NO_DEX) == 0) {
5900 for (int i = 0; i < clientLibPkgs.size(); i++) {
5901 PackageParser.Package clientPkg = clientLibPkgs.get(i);
5902 if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
5903 (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5904 throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
5905 "scanPackageLI failed to dexopt clientLibPkgs");
5911 // Request the ActivityManager to kill the process(only for existing packages)
5912 // so that we do not end up in a confused state while the user is still using the older
5913 // version of the application while the new one gets installed.
5914 if ((scanFlags & SCAN_REPLACING) != 0) {
5915 killApplication(pkg.applicationInfo.packageName,
5916 pkg.applicationInfo.uid, "update pkg");
5919 // Also need to kill any apps that are dependent on the library.
5920 if (clientLibPkgs != null) {
5921 for (int i=0; i<clientLibPkgs.size(); i++) {
5922 PackageParser.Package clientPkg = clientLibPkgs.get(i);
5923 killApplication(clientPkg.applicationInfo.packageName,
5924 clientPkg.applicationInfo.uid, "update lib");
5929 synchronized (mPackages) {
5930 // We don't expect installation to fail beyond this point
5932 // Add the new setting to mSettings
5933 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
5934 // Add the new setting to mPackages
5935 mPackages.put(pkg.applicationInfo.packageName, pkg);
5936 // Make sure we don't accidentally delete its data.
5937 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
5938 while (iter.hasNext()) {
5939 PackageCleanItem item = iter.next();
5940 if (pkgName.equals(item.packageName)) {
5945 // Take care of first install / last update times.
5946 if (currentTime != 0) {
5947 if (pkgSetting.firstInstallTime == 0) {
5948 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
5949 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
5950 pkgSetting.lastUpdateTime = currentTime;
5952 } else if (pkgSetting.firstInstallTime == 0) {
5953 // We need *something*. Take time time stamp of the file.
5954 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
5955 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
5956 if (scanFileTime != pkgSetting.timeStamp) {
5957 // A package on the system image has changed; consider this
5959 pkgSetting.lastUpdateTime = scanFileTime;
5963 // Add the package's KeySets to the global KeySetManagerService
5964 KeySetManagerService ksms = mSettings.mKeySetManagerService;
5966 // Old KeySetData no longer valid.
5967 ksms.removeAppKeySetDataLPw(pkg.packageName);
5968 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
5969 if (pkg.mKeySetMapping != null) {
5970 for (Map.Entry<String, ArraySet<PublicKey>> entry :
5971 pkg.mKeySetMapping.entrySet()) {
5972 if (entry.getValue() != null) {
5973 ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
5974 entry.getValue(), entry.getKey());
5977 if (pkg.mUpgradeKeySets != null) {
5978 for (String upgradeAlias : pkg.mUpgradeKeySets) {
5979 ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
5983 } catch (NullPointerException e) {
5984 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
5985 } catch (IllegalArgumentException e) {
5986 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
5989 int N = pkg.providers.size();
5990 StringBuilder r = null;
5992 for (i=0; i<N; i++) {
5993 PackageParser.Provider p = pkg.providers.get(i);
5994 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
5995 p.info.processName, pkg.applicationInfo.uid);
5996 mProviders.addProvider(p);
5997 p.syncable = p.info.isSyncable;
5998 if (p.info.authority != null) {
5999 String names[] = p.info.authority.split(";");
6000 p.info.authority = null;
6001 for (int j = 0; j < names.length; j++) {
6002 if (j == 1 && p.syncable) {
6003 // We only want the first authority for a provider to possibly be
6004 // syncable, so if we already added this provider using a different
6005 // authority clear the syncable flag. We copy the provider before
6006 // changing it because the mProviders object contains a reference
6007 // to a provider that we don't want to change.
6008 // Only do this for the second authority since the resulting provider
6009 // object can be the same for all future authorities for this provider.
6010 p = new PackageParser.Provider(p);
6013 if (!mProvidersByAuthority.containsKey(names[j])) {
6014 mProvidersByAuthority.put(names[j], p);
6015 if (p.info.authority == null) {
6016 p.info.authority = names[j];
6018 p.info.authority = p.info.authority + ";" + names[j];
6020 if (DEBUG_PACKAGE_SCANNING) {
6021 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6022 Log.d(TAG, "Registered content provider: " + names[j]
6023 + ", className = " + p.info.name + ", isSyncable = "
6024 + p.info.isSyncable);
6027 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6028 Slog.w(TAG, "Skipping provider name " + names[j] +
6029 " (in package " + pkg.applicationInfo.packageName +
6030 "): name already used by "
6031 + ((other != null && other.getComponentName() != null)
6032 ? other.getComponentName().getPackageName() : "?"));
6036 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6038 r = new StringBuilder(256);
6042 r.append(p.info.name);
6046 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
6049 N = pkg.services.size();
6051 for (i=0; i<N; i++) {
6052 PackageParser.Service s = pkg.services.get(i);
6053 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
6054 s.info.processName, pkg.applicationInfo.uid);
6055 mServices.addService(s);
6056 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6058 r = new StringBuilder(256);
6062 r.append(s.info.name);
6066 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
6069 N = pkg.receivers.size();
6071 for (i=0; i<N; i++) {
6072 PackageParser.Activity a = pkg.receivers.get(i);
6073 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6074 a.info.processName, pkg.applicationInfo.uid);
6075 mReceivers.addActivity(a, "receiver");
6076 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6078 r = new StringBuilder(256);
6082 r.append(a.info.name);
6086 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
6089 N = pkg.activities.size();
6091 for (i=0; i<N; i++) {
6092 PackageParser.Activity a = pkg.activities.get(i);
6093 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6094 a.info.processName, pkg.applicationInfo.uid);
6095 mActivities.addActivity(a, "activity");
6096 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6098 r = new StringBuilder(256);
6102 r.append(a.info.name);
6106 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
6109 N = pkg.permissionGroups.size();
6111 for (i=0; i<N; i++) {
6112 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
6113 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
6115 mPermissionGroups.put(pg.info.name, pg);
6116 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6118 r = new StringBuilder(256);
6122 r.append(pg.info.name);
6125 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
6126 + pg.info.packageName + " ignored: original from "
6127 + cur.info.packageName);
6128 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6130 r = new StringBuilder(256);
6135 r.append(pg.info.name);
6140 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r);
6143 N = pkg.permissions.size();
6145 for (i=0; i<N; i++) {
6146 PackageParser.Permission p = pkg.permissions.get(i);
6147 HashMap<String, BasePermission> permissionMap =
6148 p.tree ? mSettings.mPermissionTrees
6149 : mSettings.mPermissions;
6150 p.group = mPermissionGroups.get(p.info.group);
6151 if (p.info.group == null || p.group != null) {
6152 BasePermission bp = permissionMap.get(p.info.name);
6154 // Allow system apps to redefine non-system permissions
6155 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
6156 final boolean currentOwnerIsSystem = (bp.perm != null
6157 && isSystemApp(bp.perm.owner));
6158 if (isSystemApp(p.owner)) {
6159 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
6160 // It's a built-in permission and no owner, take ownership now
6161 bp.packageSetting = pkgSetting;
6163 bp.uid = pkg.applicationInfo.uid;
6164 bp.sourcePackage = p.info.packageName;
6165 } else if (!currentOwnerIsSystem) {
6166 String msg = "New decl " + p.owner + " of permission "
6167 + p.info.name + " is system; overriding " + bp.sourcePackage;
6168 reportSettingsProblem(Log.WARN, msg);
6175 bp = new BasePermission(p.info.name, p.info.packageName,
6176 BasePermission.TYPE_NORMAL);
6177 permissionMap.put(p.info.name, bp);
6180 if (bp.perm == null) {
6181 if (bp.sourcePackage == null
6182 || bp.sourcePackage.equals(p.info.packageName)) {
6183 BasePermission tree = findPermissionTreeLP(p.info.name);
6185 || tree.sourcePackage.equals(p.info.packageName)) {
6186 bp.packageSetting = pkgSetting;
6188 bp.uid = pkg.applicationInfo.uid;
6189 bp.sourcePackage = p.info.packageName;
6190 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6192 r = new StringBuilder(256);
6196 r.append(p.info.name);
6199 Slog.w(TAG, "Permission " + p.info.name + " from package "
6200 + p.info.packageName + " ignored: base tree "
6201 + tree.name + " is from package "
6202 + tree.sourcePackage);
6205 Slog.w(TAG, "Permission " + p.info.name + " from package "
6206 + p.info.packageName + " ignored: original from "
6207 + bp.sourcePackage);
6209 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6211 r = new StringBuilder(256);
6216 r.append(p.info.name);
6219 bp.protectionLevel = p.info.protectionLevel;
6222 Slog.w(TAG, "Permission " + p.info.name + " from package "
6223 + p.info.packageName + " ignored: no group "
6228 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
6231 N = pkg.instrumentation.size();
6233 for (i=0; i<N; i++) {
6234 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6235 a.info.packageName = pkg.applicationInfo.packageName;
6236 a.info.sourceDir = pkg.applicationInfo.sourceDir;
6237 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
6238 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
6239 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
6240 a.info.dataDir = pkg.applicationInfo.dataDir;
6242 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
6243 // need other information about the application, like the ABI and what not ?
6244 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
6245 mInstrumentation.put(a.getComponentName(), a);
6246 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6248 r = new StringBuilder(256);
6252 r.append(a.info.name);
6256 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
6259 if (pkg.protectedBroadcasts != null) {
6260 N = pkg.protectedBroadcasts.size();
6261 for (i=0; i<N; i++) {
6262 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
6266 pkgSetting.setTimeStamp(scanFileTime);
6268 // Create idmap files for pairs of (packages, overlay packages).
6269 // Note: "android", ie framework-res.apk, is handled by native layers.
6270 if (pkg.mOverlayTarget != null) {
6271 // This is an overlay package.
6272 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
6273 if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
6274 mOverlays.put(pkg.mOverlayTarget,
6275 new HashMap<String, PackageParser.Package>());
6277 HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
6278 map.put(pkg.packageName, pkg);
6279 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
6280 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
6281 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6282 "scanPackageLI failed to createIdmap");
6285 } else if (mOverlays.containsKey(pkg.packageName) &&
6286 !pkg.packageName.equals("android")) {
6287 // This is a regular package, with one or more known overlay packages.
6288 createIdmapsForPackageLI(pkg);
6296 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
6297 * i.e, so that all packages can be run inside a single process if required.
6299 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
6300 * this function will either try and make the ABI for all packages in {@code packagesForUser}
6301 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
6302 * the ABI selected for {@code packagesForUser}. This variant is used when installing or
6303 * updating a package that belongs to a shared user.
6305 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
6306 * adds unnecessary complexity.
6308 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
6309 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
6310 String requiredInstructionSet = null;
6311 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
6312 requiredInstructionSet = VMRuntime.getInstructionSet(
6313 scannedPackage.applicationInfo.primaryCpuAbi);
6316 PackageSetting requirer = null;
6317 for (PackageSetting ps : packagesForUser) {
6318 // If packagesForUser contains scannedPackage, we skip it. This will happen
6319 // when scannedPackage is an update of an existing package. Without this check,
6320 // we will never be able to change the ABI of any package belonging to a shared
6321 // user, even if it's compatible with other packages.
6322 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6323 if (ps.primaryCpuAbiString == null) {
6327 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
6328 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
6329 // We have a mismatch between instruction sets (say arm vs arm64) warn about
6330 // this but there's not much we can do.
6331 String errorMessage = "Instruction set mismatch, "
6332 + ((requirer == null) ? "[caller]" : requirer)
6333 + " requires " + requiredInstructionSet + " whereas " + ps
6334 + " requires " + instructionSet;
6335 Slog.w(TAG, errorMessage);
6338 if (requiredInstructionSet == null) {
6339 requiredInstructionSet = instructionSet;
6345 if (requiredInstructionSet != null) {
6347 if (requirer != null) {
6348 // requirer != null implies that either scannedPackage was null or that scannedPackage
6349 // did not require an ABI, in which case we have to adjust scannedPackage to match
6350 // the ABI of the set (which is the same as requirer's ABI)
6351 adjustedAbi = requirer.primaryCpuAbiString;
6352 if (scannedPackage != null) {
6353 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
6356 // requirer == null implies that we're updating all ABIs in the set to
6357 // match scannedPackage.
6358 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
6361 for (PackageSetting ps : packagesForUser) {
6362 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6363 if (ps.primaryCpuAbiString != null) {
6367 ps.primaryCpuAbiString = adjustedAbi;
6368 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
6369 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
6370 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
6372 if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
6373 deferDexOpt, true) == DEX_OPT_FAILED) {
6374 ps.primaryCpuAbiString = null;
6375 ps.pkg.applicationInfo.primaryCpuAbi = null;
6378 mInstaller.rmdex(ps.codePathString,
6379 getDexCodeInstructionSet(getPreferredInstructionSet()));
6387 private void setUpCustomResolverActivity(PackageParser.Package pkg) {
6388 synchronized (mPackages) {
6389 mResolverReplaced = true;
6390 // Set up information for custom user intent resolution activity.
6391 mResolveActivity.applicationInfo = pkg.applicationInfo;
6392 mResolveActivity.name = mCustomResolverComponentName.getClassName();
6393 mResolveActivity.packageName = pkg.applicationInfo.packageName;
6394 mResolveActivity.processName = null;
6395 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6396 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
6397 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
6398 mResolveActivity.theme = 0;
6399 mResolveActivity.exported = true;
6400 mResolveActivity.enabled = true;
6401 mResolveInfo.activityInfo = mResolveActivity;
6402 mResolveInfo.priority = 0;
6403 mResolveInfo.preferredOrder = 0;
6404 mResolveInfo.match = 0;
6405 mResolveComponentName = mCustomResolverComponentName;
6406 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
6407 mResolveComponentName);
6411 private static String calculateBundledApkRoot(final String codePathString) {
6412 final File codePath = new File(codePathString);
6413 final File codeRoot;
6414 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
6415 codeRoot = Environment.getRootDirectory();
6416 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
6417 codeRoot = Environment.getOemDirectory();
6418 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
6419 codeRoot = Environment.getVendorDirectory();
6421 // Unrecognized code path; take its top real segment as the apk root:
6422 // e.g. /something/app/blah.apk => /something
6424 File f = codePath.getCanonicalFile();
6425 File parent = f.getParentFile(); // non-null because codePath is a file
6427 while ((tmp = parent.getParentFile()) != null) {
6432 Slog.w(TAG, "Unrecognized code path "
6433 + codePath + " - using " + codeRoot);
6434 } catch (IOException e) {
6435 // Can't canonicalize the code path -- shenanigans?
6436 Slog.w(TAG, "Can't canonicalize code path " + codePath);
6437 return Environment.getRootDirectory().getPath();
6440 return codeRoot.getPath();
6444 * Derive and set the location of native libraries for the given package,
6445 * which varies depending on where and how the package was installed.
6447 private void setNativeLibraryPaths(PackageParser.Package pkg) {
6448 final ApplicationInfo info = pkg.applicationInfo;
6449 final String codePath = pkg.codePath;
6450 final File codeFile = new File(codePath);
6451 final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
6452 final boolean asecApp = isForwardLocked(info) || isExternal(info);
6454 info.nativeLibraryRootDir = null;
6455 info.nativeLibraryRootRequiresIsa = false;
6456 info.nativeLibraryDir = null;
6457 info.secondaryNativeLibraryDir = null;
6459 if (isApkFile(codeFile)) {
6460 // Monolithic install
6462 // If "/system/lib64/apkname" exists, assume that is the per-package
6463 // native library directory to use; otherwise use "/system/lib/apkname".
6464 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
6465 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
6466 getPrimaryInstructionSet(info));
6468 // This is a bundled system app so choose the path based on the ABI.
6469 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
6470 // is just the default path.
6471 final String apkName = deriveCodePathName(codePath);
6472 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
6473 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
6474 apkName).getAbsolutePath();
6476 if (info.secondaryCpuAbi != null) {
6477 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
6478 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
6479 secondaryLibDir, apkName).getAbsolutePath();
6481 } else if (asecApp) {
6482 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
6485 final String apkName = deriveCodePathName(codePath);
6486 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
6490 info.nativeLibraryRootRequiresIsa = false;
6491 info.nativeLibraryDir = info.nativeLibraryRootDir;
6494 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
6495 info.nativeLibraryRootRequiresIsa = true;
6497 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
6498 getPrimaryInstructionSet(info)).getAbsolutePath();
6500 if (info.secondaryCpuAbi != null) {
6501 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
6502 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
6508 * Calculate the abis and roots for a bundled app. These can uniquely
6509 * be determined from the contents of the system partition, i.e whether
6510 * it contains 64 or 32 bit shared libraries etc. We do not validate any
6511 * of this information, and instead assume that the system was built
6514 private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
6515 PackageSetting pkgSetting) {
6516 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
6518 // If "/system/lib64/apkname" exists, assume that is the per-package
6519 // native library directory to use; otherwise use "/system/lib/apkname".
6520 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
6521 setBundledAppAbi(pkg, apkRoot, apkName);
6522 // pkgSetting might be null during rescan following uninstall of updates
6523 // to a bundled app, so accommodate that possibility. The settings in
6524 // that case will be established later from the parsed package.
6526 // If the settings aren't null, sync them up with what we've just derived.
6527 // note that apkRoot isn't stored in the package settings.
6528 if (pkgSetting != null) {
6529 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
6530 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
6535 * Deduces the ABI of a bundled app and sets the relevant fields on the
6536 * parsed pkg object.
6538 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
6539 * under which system libraries are installed.
6540 * @param apkName the name of the installed package.
6542 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
6543 final File codeFile = new File(pkg.codePath);
6545 final boolean has64BitLibs;
6546 final boolean has32BitLibs;
6547 if (isApkFile(codeFile)) {
6548 // Monolithic install
6549 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
6550 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
6553 final File rootDir = new File(codeFile, LIB_DIR_NAME);
6554 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
6555 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
6556 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
6557 has64BitLibs = (new File(rootDir, isa)).exists();
6559 has64BitLibs = false;
6561 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
6562 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
6563 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
6564 has32BitLibs = (new File(rootDir, isa)).exists();
6566 has32BitLibs = false;
6570 if (has64BitLibs && !has32BitLibs) {
6571 // The package has 64 bit libs, but not 32 bit libs. Its primary
6572 // ABI should be 64 bit. We can safely assume here that the bundled
6573 // native libraries correspond to the most preferred ABI in the list.
6575 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6576 pkg.applicationInfo.secondaryCpuAbi = null;
6577 } else if (has32BitLibs && !has64BitLibs) {
6578 // The package has 32 bit libs but not 64 bit libs. Its primary
6579 // ABI should be 32 bit.
6581 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6582 pkg.applicationInfo.secondaryCpuAbi = null;
6583 } else if (has32BitLibs && has64BitLibs) {
6584 // The application has both 64 and 32 bit bundled libraries. We check
6585 // here that the app declares multiArch support, and warn if it doesn't.
6587 // We will be lenient here and record both ABIs. The primary will be the
6588 // ABI that's higher on the list, i.e, a device that's configured to prefer
6589 // 64 bit apps will see a 64 bit primary ABI,
6591 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
6592 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
6595 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
6596 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6597 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6599 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6600 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6603 pkg.applicationInfo.primaryCpuAbi = null;
6604 pkg.applicationInfo.secondaryCpuAbi = null;
6608 private void killApplication(String pkgName, int appId, String reason) {
6609 // Request the ActivityManager to kill the process(only for existing packages)
6610 // so that we do not end up in a confused state while the user is still using the older
6611 // version of the application while the new one gets installed.
6612 IActivityManager am = ActivityManagerNative.getDefault();
6615 am.killApplicationWithAppId(pkgName, appId, reason);
6616 } catch (RemoteException e) {
6621 void removePackageLI(PackageSetting ps, boolean chatty) {
6622 if (DEBUG_INSTALL) {
6624 Log.d(TAG, "Removing package " + ps.name);
6628 synchronized (mPackages) {
6629 mPackages.remove(ps.name);
6630 final PackageParser.Package pkg = ps.pkg;
6632 cleanPackageDataStructuresLILPw(pkg, chatty);
6637 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
6638 if (DEBUG_INSTALL) {
6640 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
6644 synchronized (mPackages) {
6645 mPackages.remove(pkg.applicationInfo.packageName);
6646 cleanPackageDataStructuresLILPw(pkg, chatty);
6650 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
6651 int N = pkg.providers.size();
6652 StringBuilder r = null;
6654 for (i=0; i<N; i++) {
6655 PackageParser.Provider p = pkg.providers.get(i);
6656 mProviders.removeProvider(p);
6657 if (p.info.authority == null) {
6659 /* There was another ContentProvider with this authority when
6660 * this app was installed so this authority is null,
6661 * Ignore it as we don't have to unregister the provider.
6665 String names[] = p.info.authority.split(";");
6666 for (int j = 0; j < names.length; j++) {
6667 if (mProvidersByAuthority.get(names[j]) == p) {
6668 mProvidersByAuthority.remove(names[j]);
6671 Log.d(TAG, "Unregistered content provider: " + names[j]
6672 + ", className = " + p.info.name + ", isSyncable = "
6673 + p.info.isSyncable);
6677 if (DEBUG_REMOVE && chatty) {
6679 r = new StringBuilder(256);
6683 r.append(p.info.name);
6687 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
6690 N = pkg.services.size();
6692 for (i=0; i<N; i++) {
6693 PackageParser.Service s = pkg.services.get(i);
6694 mServices.removeService(s);
6697 r = new StringBuilder(256);
6701 r.append(s.info.name);
6705 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
6708 N = pkg.receivers.size();
6710 for (i=0; i<N; i++) {
6711 PackageParser.Activity a = pkg.receivers.get(i);
6712 mReceivers.removeActivity(a, "receiver");
6713 if (DEBUG_REMOVE && chatty) {
6715 r = new StringBuilder(256);
6719 r.append(a.info.name);
6723 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
6726 N = pkg.activities.size();
6728 for (i=0; i<N; i++) {
6729 PackageParser.Activity a = pkg.activities.get(i);
6730 mActivities.removeActivity(a, "activity");
6731 if (DEBUG_REMOVE && chatty) {
6733 r = new StringBuilder(256);
6737 r.append(a.info.name);
6741 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
6744 N = pkg.permissions.size();
6746 for (i=0; i<N; i++) {
6747 PackageParser.Permission p = pkg.permissions.get(i);
6748 BasePermission bp = mSettings.mPermissions.get(p.info.name);
6750 bp = mSettings.mPermissionTrees.get(p.info.name);
6752 if (bp != null && bp.perm == p) {
6754 if (DEBUG_REMOVE && chatty) {
6756 r = new StringBuilder(256);
6760 r.append(p.info.name);
6763 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6764 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
6765 if (appOpPerms != null) {
6766 appOpPerms.remove(pkg.packageName);
6771 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
6774 N = pkg.requestedPermissions.size();
6776 for (i=0; i<N; i++) {
6777 String perm = pkg.requestedPermissions.get(i);
6778 BasePermission bp = mSettings.mPermissions.get(perm);
6779 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6780 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
6781 if (appOpPerms != null) {
6782 appOpPerms.remove(pkg.packageName);
6783 if (appOpPerms.isEmpty()) {
6784 mAppOpPermissionPackages.remove(perm);
6790 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
6793 N = pkg.instrumentation.size();
6795 for (i=0; i<N; i++) {
6796 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6797 mInstrumentation.remove(a.getComponentName());
6798 if (DEBUG_REMOVE && chatty) {
6800 r = new StringBuilder(256);
6804 r.append(a.info.name);
6808 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
6812 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6813 // Only system apps can hold shared libraries.
6814 if (pkg.libraryNames != null) {
6815 for (i=0; i<pkg.libraryNames.size(); i++) {
6816 String name = pkg.libraryNames.get(i);
6817 SharedLibraryEntry cur = mSharedLibraries.get(name);
6818 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
6819 mSharedLibraries.remove(name);
6820 if (DEBUG_REMOVE && chatty) {
6822 r = new StringBuilder(256);
6833 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
6837 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
6838 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
6839 if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
6846 static final int UPDATE_PERMISSIONS_ALL = 1<<0;
6847 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
6848 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
6850 private void updatePermissionsLPw(String changingPkg,
6851 PackageParser.Package pkgInfo, int flags) {
6852 // Make sure there are no dangling permission trees.
6853 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
6854 while (it.hasNext()) {
6855 final BasePermission bp = it.next();
6856 if (bp.packageSetting == null) {
6857 // We may not yet have parsed the package, so just see if
6858 // we still know about its settings.
6859 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6861 if (bp.packageSetting == null) {
6862 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
6863 + " from package " + bp.sourcePackage);
6865 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6866 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6867 Slog.i(TAG, "Removing old permission tree: " + bp.name
6868 + " from package " + bp.sourcePackage);
6869 flags |= UPDATE_PERMISSIONS_ALL;
6875 // Make sure all dynamic permissions have been assigned to a package,
6876 // and make sure there are no dangling permissions.
6877 it = mSettings.mPermissions.values().iterator();
6878 while (it.hasNext()) {
6879 final BasePermission bp = it.next();
6880 if (bp.type == BasePermission.TYPE_DYNAMIC) {
6881 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
6882 + bp.name + " pkg=" + bp.sourcePackage
6883 + " info=" + bp.pendingInfo);
6884 if (bp.packageSetting == null && bp.pendingInfo != null) {
6885 final BasePermission tree = findPermissionTreeLP(bp.name);
6886 if (tree != null && tree.perm != null) {
6887 bp.packageSetting = tree.packageSetting;
6888 bp.perm = new PackageParser.Permission(tree.perm.owner,
6889 new PermissionInfo(bp.pendingInfo));
6890 bp.perm.info.packageName = tree.perm.info.packageName;
6891 bp.perm.info.name = bp.name;
6896 if (bp.packageSetting == null) {
6897 // We may not yet have parsed the package, so just see if
6898 // we still know about its settings.
6899 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6901 if (bp.packageSetting == null) {
6902 Slog.w(TAG, "Removing dangling permission: " + bp.name
6903 + " from package " + bp.sourcePackage);
6905 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6906 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6907 Slog.i(TAG, "Removing old permission: " + bp.name
6908 + " from package " + bp.sourcePackage);
6909 flags |= UPDATE_PERMISSIONS_ALL;
6915 // Now update the permissions for all packages, in particular
6916 // replace the granted permissions of the system packages.
6917 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
6918 for (PackageParser.Package pkg : mPackages.values()) {
6919 if (pkg != pkgInfo) {
6920 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
6926 if (pkgInfo != null) {
6927 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
6931 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
6932 String packageOfInterest) {
6933 final PackageSetting ps = (PackageSetting) pkg.mExtras;
6937 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
6938 HashSet<String> origPermissions = gp.grantedPermissions;
6939 boolean changedPermission = false;
6942 ps.permissionsFixed = false;
6944 origPermissions = new HashSet<String>(gp.grantedPermissions);
6945 gp.grantedPermissions.clear();
6946 gp.gids = mGlobalGids;
6950 if (gp.gids == null) {
6951 gp.gids = mGlobalGids;
6954 final int N = pkg.requestedPermissions.size();
6955 for (int i=0; i<N; i++) {
6956 final String name = pkg.requestedPermissions.get(i);
6957 final boolean required = pkg.requestedPermissionsRequired.get(i);
6958 final BasePermission bp = mSettings.mPermissions.get(name);
6959 if (DEBUG_INSTALL) {
6961 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
6965 if (bp == null || bp.packageSetting == null) {
6966 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
6967 Slog.w(TAG, "Unknown permission " + name
6968 + " in package " + pkg.packageName);
6973 final String perm = bp.name;
6975 boolean allowedSig = false;
6976 if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6977 // Keep track of app op permissions.
6978 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
6980 pkgs = new ArraySet<>();
6981 mAppOpPermissionPackages.put(bp.name, pkgs);
6983 pkgs.add(pkg.packageName);
6985 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
6986 if (level == PermissionInfo.PROTECTION_NORMAL
6987 || level == PermissionInfo.PROTECTION_DANGEROUS) {
6988 // We grant a normal or dangerous permission if any of the following
6990 // 1) The permission is required
6991 // 2) The permission is optional, but was granted in the past
6992 // 3) The permission is optional, but was requested by an
6993 // app in /system (not /data)
6995 // Otherwise, reject the permission.
6996 allowed = (required || origPermissions.contains(perm)
6997 || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
6998 } else if (bp.packageSetting == null) {
6999 // This permission is invalid; skip it.
7001 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
7002 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
7009 if (DEBUG_INSTALL) {
7011 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
7015 if (!isSystemApp(ps) && ps.permissionsFixed) {
7016 // If this is an existing, non-system package, then
7017 // we can't add any new permissions to it.
7018 if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
7019 // Except... if this is a permission that was added
7020 // to the platform (note: need to only do this when
7021 // updating the platform).
7022 allowed = isNewPlatformPermissionForPackage(perm, pkg);
7026 if (!gp.grantedPermissions.contains(perm)) {
7027 changedPermission = true;
7028 gp.grantedPermissions.add(perm);
7029 gp.gids = appendInts(gp.gids, bp.gids);
7030 } else if (!ps.haveGids) {
7031 gp.gids = appendInts(gp.gids, bp.gids);
7034 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7035 Slog.w(TAG, "Not granting permission " + perm
7036 + " to package " + pkg.packageName
7037 + " because it was previously installed without");
7041 if (gp.grantedPermissions.remove(perm)) {
7042 changedPermission = true;
7043 gp.gids = removeInts(gp.gids, bp.gids);
7044 Slog.i(TAG, "Un-granting permission " + perm
7045 + " from package " + pkg.packageName
7046 + " (protectionLevel=" + bp.protectionLevel
7047 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7049 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
7050 // Don't print warning for app op permissions, since it is fine for them
7051 // not to be granted, there is a UI for the user to decide.
7052 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7053 Slog.w(TAG, "Not granting permission " + perm
7054 + " to package " + pkg.packageName
7055 + " (protectionLevel=" + bp.protectionLevel
7056 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7063 if ((changedPermission || replace) && !ps.permissionsFixed &&
7064 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
7065 // This is the first that we have heard about this package, so the
7066 // permissions we have now selected are fixed until explicitly
7068 ps.permissionsFixed = true;
7073 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
7074 boolean allowed = false;
7075 final int NP = PackageParser.NEW_PERMISSIONS.length;
7076 for (int ip=0; ip<NP; ip++) {
7077 final PackageParser.NewPermissionInfo npi
7078 = PackageParser.NEW_PERMISSIONS[ip];
7079 if (npi.name.equals(perm)
7080 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
7082 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
7090 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
7091 BasePermission bp, HashSet<String> origPermissions) {
7093 allowed = (compareSignatures(
7094 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
7095 == PackageManager.SIGNATURE_MATCH)
7096 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
7097 == PackageManager.SIGNATURE_MATCH);
7098 if (!allowed && (bp.protectionLevel
7099 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
7100 if (isSystemApp(pkg)) {
7101 // For updated system applications, a system permission
7102 // is granted only if it had been defined by the original application.
7103 if (isUpdatedSystemApp(pkg)) {
7104 final PackageSetting sysPs = mSettings
7105 .getDisabledSystemPkgLPr(pkg.packageName);
7106 final GrantedPermissions origGp = sysPs.sharedUser != null
7107 ? sysPs.sharedUser : sysPs;
7109 if (origGp.grantedPermissions.contains(perm)) {
7110 // If the original was granted this permission, we take
7111 // that grant decision as read and propagate it to the
7115 // The system apk may have been updated with an older
7116 // version of the one on the data partition, but which
7117 // granted a new system permission that it didn't have
7118 // before. In this case we do want to allow the app to
7119 // now get the new permission if the ancestral apk is
7120 // privileged to get it.
7121 if (sysPs.pkg != null && sysPs.isPrivileged()) {
7123 j<sysPs.pkg.requestedPermissions.size(); j++) {
7125 sysPs.pkg.requestedPermissions.get(j))) {
7133 allowed = isPrivilegedApp(pkg);
7137 if (!allowed && (bp.protectionLevel
7138 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
7139 // For development permissions, a development permission
7140 // is granted only if it was already granted.
7141 allowed = origPermissions.contains(perm);
7146 final class ActivityIntentResolver
7147 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
7148 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7149 boolean defaultOnly, int userId) {
7150 if (!sUserManager.exists(userId)) return null;
7151 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7152 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7155 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7157 if (!sUserManager.exists(userId)) return null;
7159 return super.queryIntent(intent, resolvedType,
7160 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7163 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7164 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
7165 if (!sUserManager.exists(userId)) return null;
7166 if (packageActivities == null) {
7170 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7171 final int N = packageActivities.size();
7172 ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
7173 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
7175 ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
7176 for (int i = 0; i < N; ++i) {
7177 intentFilters = packageActivities.get(i).intents;
7178 if (intentFilters != null && intentFilters.size() > 0) {
7179 PackageParser.ActivityIntentInfo[] array =
7180 new PackageParser.ActivityIntentInfo[intentFilters.size()];
7181 intentFilters.toArray(array);
7185 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7188 public final void addActivity(PackageParser.Activity a, String type) {
7189 final boolean systemApp = isSystemApp(a.info.applicationInfo);
7190 mActivities.put(a.getComponentName(), a);
7191 if (DEBUG_SHOW_INFO)
7193 TAG, " " + type + " " +
7194 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
7195 if (DEBUG_SHOW_INFO)
7196 Log.v(TAG, " Class=" + a.info.name);
7197 final int NI = a.intents.size();
7198 for (int j=0; j<NI; j++) {
7199 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7200 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
7201 intent.setPriority(0);
7202 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
7203 + a.className + " with priority > 0, forcing to 0");
7205 if (DEBUG_SHOW_INFO) {
7206 Log.v(TAG, " IntentFilter:");
7207 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7209 if (!intent.debugCheck()) {
7210 Log.w(TAG, "==> For Activity " + a.info.name);
7216 public final void removeActivity(PackageParser.Activity a, String type) {
7217 mActivities.remove(a.getComponentName());
7218 if (DEBUG_SHOW_INFO) {
7219 Log.v(TAG, " " + type + " "
7220 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
7221 : a.info.name) + ":");
7222 Log.v(TAG, " Class=" + a.info.name);
7224 final int NI = a.intents.size();
7225 for (int j=0; j<NI; j++) {
7226 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7227 if (DEBUG_SHOW_INFO) {
7228 Log.v(TAG, " IntentFilter:");
7229 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7231 removeFilter(intent);
7236 protected boolean allowFilterResult(
7237 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
7238 ActivityInfo filterAi = filter.activity.info;
7239 for (int i=dest.size()-1; i>=0; i--) {
7240 ActivityInfo destAi = dest.get(i).activityInfo;
7241 if (destAi.name == filterAi.name
7242 && destAi.packageName == filterAi.packageName) {
7250 protected ActivityIntentInfo[] newArray(int size) {
7251 return new ActivityIntentInfo[size];
7255 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
7256 if (!sUserManager.exists(userId)) return true;
7257 PackageParser.Package p = filter.activity.owner;
7259 PackageSetting ps = (PackageSetting)p.mExtras;
7261 // System apps are never considered stopped for purposes of
7262 // filtering, because there may be no way for the user to
7263 // actually re-launch them.
7264 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
7265 && ps.getStopped(userId);
7272 protected boolean isPackageForFilter(String packageName,
7273 PackageParser.ActivityIntentInfo info) {
7274 return packageName.equals(info.activity.owner.packageName);
7278 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
7279 int match, int userId) {
7280 if (!sUserManager.exists(userId)) return null;
7281 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
7284 final PackageParser.Activity activity = info.activity;
7285 if (mSafeMode && (activity.info.applicationInfo.flags
7286 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7289 PackageSetting ps = (PackageSetting) activity.owner.mExtras;
7293 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
7294 ps.readUserState(userId), userId);
7298 final ResolveInfo res = new ResolveInfo();
7299 res.activityInfo = ai;
7300 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7303 res.priority = info.getPriority();
7304 res.preferredOrder = activity.owner.mPreferredOrder;
7305 //System.out.println("Result: " + res.activityInfo.className +
7306 // " = " + res.priority);
7308 res.isDefault = info.hasDefault;
7309 res.labelRes = info.labelRes;
7310 res.nonLocalizedLabel = info.nonLocalizedLabel;
7311 if (userNeedsBadging(userId)) {
7312 res.noResourceId = true;
7314 res.icon = info.icon;
7316 res.system = isSystemApp(res.activityInfo.applicationInfo);
7321 protected void sortResults(List<ResolveInfo> results) {
7322 Collections.sort(results, mResolvePrioritySorter);
7326 protected void dumpFilter(PrintWriter out, String prefix,
7327 PackageParser.ActivityIntentInfo filter) {
7328 out.print(prefix); out.print(
7329 Integer.toHexString(System.identityHashCode(filter.activity)));
7331 filter.activity.printComponentShortName(out);
7332 out.print(" filter ");
7333 out.println(Integer.toHexString(System.identityHashCode(filter)));
7336 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7337 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7338 // final List<ResolveInfo> retList = Lists.newArrayList();
7339 // while (i.hasNext()) {
7340 // final ResolveInfo resolveInfo = i.next();
7341 // if (isEnabledLP(resolveInfo.activityInfo)) {
7342 // retList.add(resolveInfo);
7348 // Keys are String (activity class name), values are Activity.
7349 private final HashMap<ComponentName, PackageParser.Activity> mActivities
7350 = new HashMap<ComponentName, PackageParser.Activity>();
7354 private final class ServiceIntentResolver
7355 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
7356 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7357 boolean defaultOnly, int userId) {
7358 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7359 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7362 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7364 if (!sUserManager.exists(userId)) return null;
7366 return super.queryIntent(intent, resolvedType,
7367 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7370 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7371 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
7372 if (!sUserManager.exists(userId)) return null;
7373 if (packageServices == null) {
7377 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7378 final int N = packageServices.size();
7379 ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
7380 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
7382 ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
7383 for (int i = 0; i < N; ++i) {
7384 intentFilters = packageServices.get(i).intents;
7385 if (intentFilters != null && intentFilters.size() > 0) {
7386 PackageParser.ServiceIntentInfo[] array =
7387 new PackageParser.ServiceIntentInfo[intentFilters.size()];
7388 intentFilters.toArray(array);
7392 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7395 public final void addService(PackageParser.Service s) {
7396 mServices.put(s.getComponentName(), s);
7397 if (DEBUG_SHOW_INFO) {
7399 + (s.info.nonLocalizedLabel != null
7400 ? s.info.nonLocalizedLabel : s.info.name) + ":");
7401 Log.v(TAG, " Class=" + s.info.name);
7403 final int NI = s.intents.size();
7405 for (j=0; j<NI; j++) {
7406 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7407 if (DEBUG_SHOW_INFO) {
7408 Log.v(TAG, " IntentFilter:");
7409 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7411 if (!intent.debugCheck()) {
7412 Log.w(TAG, "==> For Service " + s.info.name);
7418 public final void removeService(PackageParser.Service s) {
7419 mServices.remove(s.getComponentName());
7420 if (DEBUG_SHOW_INFO) {
7421 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
7422 ? s.info.nonLocalizedLabel : s.info.name) + ":");
7423 Log.v(TAG, " Class=" + s.info.name);
7425 final int NI = s.intents.size();
7427 for (j=0; j<NI; j++) {
7428 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7429 if (DEBUG_SHOW_INFO) {
7430 Log.v(TAG, " IntentFilter:");
7431 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7433 removeFilter(intent);
7438 protected boolean allowFilterResult(
7439 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
7440 ServiceInfo filterSi = filter.service.info;
7441 for (int i=dest.size()-1; i>=0; i--) {
7442 ServiceInfo destAi = dest.get(i).serviceInfo;
7443 if (destAi.name == filterSi.name
7444 && destAi.packageName == filterSi.packageName) {
7452 protected PackageParser.ServiceIntentInfo[] newArray(int size) {
7453 return new PackageParser.ServiceIntentInfo[size];
7457 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
7458 if (!sUserManager.exists(userId)) return true;
7459 PackageParser.Package p = filter.service.owner;
7461 PackageSetting ps = (PackageSetting)p.mExtras;
7463 // System apps are never considered stopped for purposes of
7464 // filtering, because there may be no way for the user to
7465 // actually re-launch them.
7466 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7467 && ps.getStopped(userId);
7474 protected boolean isPackageForFilter(String packageName,
7475 PackageParser.ServiceIntentInfo info) {
7476 return packageName.equals(info.service.owner.packageName);
7480 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
7481 int match, int userId) {
7482 if (!sUserManager.exists(userId)) return null;
7483 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
7484 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
7487 final PackageParser.Service service = info.service;
7488 if (mSafeMode && (service.info.applicationInfo.flags
7489 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7492 PackageSetting ps = (PackageSetting) service.owner.mExtras;
7496 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
7497 ps.readUserState(userId), userId);
7501 final ResolveInfo res = new ResolveInfo();
7502 res.serviceInfo = si;
7503 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7504 res.filter = filter;
7506 res.priority = info.getPriority();
7507 res.preferredOrder = service.owner.mPreferredOrder;
7508 //System.out.println("Result: " + res.activityInfo.className +
7509 // " = " + res.priority);
7511 res.isDefault = info.hasDefault;
7512 res.labelRes = info.labelRes;
7513 res.nonLocalizedLabel = info.nonLocalizedLabel;
7514 res.icon = info.icon;
7515 res.system = isSystemApp(res.serviceInfo.applicationInfo);
7520 protected void sortResults(List<ResolveInfo> results) {
7521 Collections.sort(results, mResolvePrioritySorter);
7525 protected void dumpFilter(PrintWriter out, String prefix,
7526 PackageParser.ServiceIntentInfo filter) {
7527 out.print(prefix); out.print(
7528 Integer.toHexString(System.identityHashCode(filter.service)));
7530 filter.service.printComponentShortName(out);
7531 out.print(" filter ");
7532 out.println(Integer.toHexString(System.identityHashCode(filter)));
7535 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7536 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7537 // final List<ResolveInfo> retList = Lists.newArrayList();
7538 // while (i.hasNext()) {
7539 // final ResolveInfo resolveInfo = (ResolveInfo) i;
7540 // if (isEnabledLP(resolveInfo.serviceInfo)) {
7541 // retList.add(resolveInfo);
7547 // Keys are String (activity class name), values are Activity.
7548 private final HashMap<ComponentName, PackageParser.Service> mServices
7549 = new HashMap<ComponentName, PackageParser.Service>();
7553 private final class ProviderIntentResolver
7554 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
7555 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7556 boolean defaultOnly, int userId) {
7557 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7558 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7561 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7563 if (!sUserManager.exists(userId))
7566 return super.queryIntent(intent, resolvedType,
7567 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7570 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7571 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
7572 if (!sUserManager.exists(userId))
7574 if (packageProviders == null) {
7578 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
7579 final int N = packageProviders.size();
7580 ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
7581 new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
7583 ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
7584 for (int i = 0; i < N; ++i) {
7585 intentFilters = packageProviders.get(i).intents;
7586 if (intentFilters != null && intentFilters.size() > 0) {
7587 PackageParser.ProviderIntentInfo[] array =
7588 new PackageParser.ProviderIntentInfo[intentFilters.size()];
7589 intentFilters.toArray(array);
7593 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7596 public final void addProvider(PackageParser.Provider p) {
7597 if (mProviders.containsKey(p.getComponentName())) {
7598 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
7602 mProviders.put(p.getComponentName(), p);
7603 if (DEBUG_SHOW_INFO) {
7605 + (p.info.nonLocalizedLabel != null
7606 ? p.info.nonLocalizedLabel : p.info.name) + ":");
7607 Log.v(TAG, " Class=" + p.info.name);
7609 final int NI = p.intents.size();
7611 for (j = 0; j < NI; j++) {
7612 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7613 if (DEBUG_SHOW_INFO) {
7614 Log.v(TAG, " IntentFilter:");
7615 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7617 if (!intent.debugCheck()) {
7618 Log.w(TAG, "==> For Provider " + p.info.name);
7624 public final void removeProvider(PackageParser.Provider p) {
7625 mProviders.remove(p.getComponentName());
7626 if (DEBUG_SHOW_INFO) {
7627 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
7628 ? p.info.nonLocalizedLabel : p.info.name) + ":");
7629 Log.v(TAG, " Class=" + p.info.name);
7631 final int NI = p.intents.size();
7633 for (j = 0; j < NI; j++) {
7634 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7635 if (DEBUG_SHOW_INFO) {
7636 Log.v(TAG, " IntentFilter:");
7637 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7639 removeFilter(intent);
7644 protected boolean allowFilterResult(
7645 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
7646 ProviderInfo filterPi = filter.provider.info;
7647 for (int i = dest.size() - 1; i >= 0; i--) {
7648 ProviderInfo destPi = dest.get(i).providerInfo;
7649 if (destPi.name == filterPi.name
7650 && destPi.packageName == filterPi.packageName) {
7658 protected PackageParser.ProviderIntentInfo[] newArray(int size) {
7659 return new PackageParser.ProviderIntentInfo[size];
7663 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
7664 if (!sUserManager.exists(userId))
7666 PackageParser.Package p = filter.provider.owner;
7668 PackageSetting ps = (PackageSetting) p.mExtras;
7670 // System apps are never considered stopped for purposes of
7671 // filtering, because there may be no way for the user to
7672 // actually re-launch them.
7673 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7674 && ps.getStopped(userId);
7681 protected boolean isPackageForFilter(String packageName,
7682 PackageParser.ProviderIntentInfo info) {
7683 return packageName.equals(info.provider.owner.packageName);
7687 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
7688 int match, int userId) {
7689 if (!sUserManager.exists(userId))
7691 final PackageParser.ProviderIntentInfo info = filter;
7692 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
7695 final PackageParser.Provider provider = info.provider;
7696 if (mSafeMode && (provider.info.applicationInfo.flags
7697 & ApplicationInfo.FLAG_SYSTEM) == 0) {
7700 PackageSetting ps = (PackageSetting) provider.owner.mExtras;
7704 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
7705 ps.readUserState(userId), userId);
7709 final ResolveInfo res = new ResolveInfo();
7710 res.providerInfo = pi;
7711 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
7712 res.filter = filter;
7714 res.priority = info.getPriority();
7715 res.preferredOrder = provider.owner.mPreferredOrder;
7717 res.isDefault = info.hasDefault;
7718 res.labelRes = info.labelRes;
7719 res.nonLocalizedLabel = info.nonLocalizedLabel;
7720 res.icon = info.icon;
7721 res.system = isSystemApp(res.providerInfo.applicationInfo);
7726 protected void sortResults(List<ResolveInfo> results) {
7727 Collections.sort(results, mResolvePrioritySorter);
7731 protected void dumpFilter(PrintWriter out, String prefix,
7732 PackageParser.ProviderIntentInfo filter) {
7735 Integer.toHexString(System.identityHashCode(filter.provider)));
7737 filter.provider.printComponentShortName(out);
7738 out.print(" filter ");
7739 out.println(Integer.toHexString(System.identityHashCode(filter)));
7742 private final HashMap<ComponentName, PackageParser.Provider> mProviders
7743 = new HashMap<ComponentName, PackageParser.Provider>();
7747 private static final Comparator<ResolveInfo> mResolvePrioritySorter =
7748 new Comparator<ResolveInfo>() {
7749 public int compare(ResolveInfo r1, ResolveInfo r2) {
7750 int v1 = r1.priority;
7751 int v2 = r2.priority;
7752 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
7754 return (v1 > v2) ? -1 : 1;
7756 v1 = r1.preferredOrder;
7757 v2 = r2.preferredOrder;
7759 return (v1 > v2) ? -1 : 1;
7761 if (r1.isDefault != r2.isDefault) {
7762 return r1.isDefault ? -1 : 1;
7766 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
7768 return (v1 > v2) ? -1 : 1;
7770 if (r1.system != r2.system) {
7771 return r1.system ? -1 : 1;
7777 private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
7778 new Comparator<ProviderInfo>() {
7779 public int compare(ProviderInfo p1, ProviderInfo p2) {
7780 final int v1 = p1.initOrder;
7781 final int v2 = p2.initOrder;
7782 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
7786 static final void sendPackageBroadcast(String action, String pkg,
7787 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
7789 IActivityManager am = ActivityManagerNative.getDefault();
7792 if (userIds == null) {
7793 userIds = am.getRunningUserIds();
7795 for (int id : userIds) {
7796 final Intent intent = new Intent(action,
7797 pkg != null ? Uri.fromParts("package", pkg, null) : null);
7798 if (extras != null) {
7799 intent.putExtras(extras);
7801 if (targetPkg != null) {
7802 intent.setPackage(targetPkg);
7804 // Modify the UID when posting to other users
7805 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
7806 if (uid > 0 && UserHandle.getUserId(uid) != id) {
7807 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
7808 intent.putExtra(Intent.EXTRA_UID, uid);
7810 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
7811 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
7812 if (DEBUG_BROADCASTS) {
7813 RuntimeException here = new RuntimeException("here");
7814 here.fillInStackTrace();
7815 Slog.d(TAG, "Sending to user " + id + ": "
7816 + intent.toShortString(false, true, false, false)
7817 + " " + intent.getExtras(), here);
7819 am.broadcastIntent(null, intent, null, finishedReceiver,
7820 0, null, null, null, android.app.AppOpsManager.OP_NONE,
7821 finishedReceiver != null, false, id);
7823 } catch (RemoteException ex) {
7829 * Check if the external storage media is available. This is true if there
7830 * is a mounted external storage medium or if the external storage is
7833 private boolean isExternalMediaAvailable() {
7834 return mMediaMounted || Environment.isExternalStorageEmulated();
7838 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
7840 synchronized (mPackages) {
7841 if (!isExternalMediaAvailable()) {
7842 // If the external storage is no longer mounted at this point,
7843 // the caller may not have been able to delete all of this
7844 // packages files and can not delete any more. Bail.
7847 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
7848 if (lastPackage != null) {
7849 pkgs.remove(lastPackage);
7851 if (pkgs.size() > 0) {
7858 void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
7859 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
7860 userId, andCode ? 1 : 0, packageName);
7864 if (mPostSystemReadyMessages == null) {
7865 mPostSystemReadyMessages = new ArrayList<>();
7867 mPostSystemReadyMessages.add(msg);
7871 void startCleaningPackages() {
7873 synchronized (mPackages) {
7874 if (!isExternalMediaAvailable()) {
7877 if (mSettings.mPackagesToBeCleaned.isEmpty()) {
7881 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
7882 intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
7883 IActivityManager am = ActivityManagerNative.getDefault();
7886 am.startService(null, intent, null, UserHandle.USER_OWNER);
7887 } catch (RemoteException e) {
7893 public void installPackage(String originPath, IPackageInstallObserver2 observer,
7894 int installFlags, String installerPackageName, VerificationParams verificationParams,
7895 String packageAbiOverride) {
7896 installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
7897 packageAbiOverride, UserHandle.getCallingUserId());
7901 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
7902 int installFlags, String installerPackageName, VerificationParams verificationParams,
7903 String packageAbiOverride, int userId) {
7904 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
7906 final int callingUid = Binder.getCallingUid();
7907 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
7909 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
7911 if (observer != null) {
7912 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
7914 } catch (RemoteException re) {
7919 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
7920 installFlags |= PackageManager.INSTALL_FROM_ADB;
7923 // Caller holds INSTALL_PACKAGES permission, so we're less strict
7924 // about installerPackageName.
7926 installFlags &= ~PackageManager.INSTALL_FROM_ADB;
7927 installFlags &= ~PackageManager.INSTALL_ALL_USERS;
7931 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
7932 user = UserHandle.ALL;
7934 user = new UserHandle(userId);
7937 verificationParams.setInstallerUid(callingUid);
7939 final File originFile = new File(originPath);
7940 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
7942 final Message msg = mHandler.obtainMessage(INIT_COPY);
7943 msg.obj = new InstallParams(origin, observer, installFlags,
7944 installerPackageName, verificationParams, user, packageAbiOverride);
7945 mHandler.sendMessage(msg);
7948 void installStage(String packageName, File stagedDir, String stagedCid,
7949 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
7950 String installerPackageName, int installerUid, UserHandle user) {
7951 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
7952 params.referrerUri, installerUid, null);
7954 final OriginInfo origin;
7955 if (stagedDir != null) {
7956 origin = OriginInfo.fromStagedFile(stagedDir);
7958 origin = OriginInfo.fromStagedContainer(stagedCid);
7961 final Message msg = mHandler.obtainMessage(INIT_COPY);
7962 msg.obj = new InstallParams(origin, observer, params.installFlags,
7963 installerPackageName, verifParams, user, params.abiOverride);
7964 mHandler.sendMessage(msg);
7967 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
7968 Bundle extras = new Bundle(1);
7969 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
7971 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
7972 packageName, extras, null, null, new int[] {userId});
7974 IActivityManager am = ActivityManagerNative.getDefault();
7975 final boolean isSystem =
7976 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
7977 if (isSystem && am.isUserRunning(userId, false)) {
7978 // The just-installed/enabled app is bundled on the system, so presumed
7979 // to be able to run automatically without needing an explicit launch.
7980 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
7981 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
7982 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
7983 .setPackage(packageName);
7984 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
7985 android.app.AppOpsManager.OP_NONE, false, false, userId);
7987 } catch (RemoteException e) {
7989 Slog.w(TAG, "Unable to bootstrap installed package", e);
7994 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
7996 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
7997 PackageSetting pkgSetting;
7998 final int uid = Binder.getCallingUid();
7999 enforceCrossUserPermission(uid, userId, true, true,
8000 "setApplicationHiddenSetting for user " + userId);
8002 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
8003 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
8007 long callingId = Binder.clearCallingIdentity();
8009 boolean sendAdded = false;
8010 boolean sendRemoved = false;
8012 synchronized (mPackages) {
8013 pkgSetting = mSettings.mPackages.get(packageName);
8014 if (pkgSetting == null) {
8017 if (pkgSetting.getHidden(userId) != hidden) {
8018 pkgSetting.setHidden(hidden, userId);
8019 mSettings.writePackageRestrictionsLPr(userId);
8028 sendPackageAddedForUser(packageName, pkgSetting, userId);
8032 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
8034 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
8037 Binder.restoreCallingIdentity(callingId);
8042 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
8044 final PackageRemovedInfo info = new PackageRemovedInfo();
8045 info.removedPackage = packageName;
8046 info.removedUsers = new int[] {userId};
8047 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
8048 info.sendBroadcast(false, false, false);
8052 * Returns true if application is not found or there was an error. Otherwise it returns
8053 * the hidden state of the package for the given user.
8056 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
8057 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8058 enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
8059 false, "getApplicationHidden for user " + userId);
8060 PackageSetting pkgSetting;
8061 long callingId = Binder.clearCallingIdentity();
8064 synchronized (mPackages) {
8065 pkgSetting = mSettings.mPackages.get(packageName);
8066 if (pkgSetting == null) {
8069 return pkgSetting.getHidden(userId);
8072 Binder.restoreCallingIdentity(callingId);
8080 public int installExistingPackageAsUser(String packageName, int userId) {
8081 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
8083 PackageSetting pkgSetting;
8084 final int uid = Binder.getCallingUid();
8085 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
8087 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8088 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
8091 long callingId = Binder.clearCallingIdentity();
8093 boolean sendAdded = false;
8094 Bundle extras = new Bundle(1);
8097 synchronized (mPackages) {
8098 pkgSetting = mSettings.mPackages.get(packageName);
8099 if (pkgSetting == null) {
8100 return PackageManager.INSTALL_FAILED_INVALID_URI;
8102 if (!pkgSetting.getInstalled(userId)) {
8103 pkgSetting.setInstalled(true, userId);
8104 pkgSetting.setHidden(false, userId);
8105 mSettings.writePackageRestrictionsLPr(userId);
8111 sendPackageAddedForUser(packageName, pkgSetting, userId);
8114 Binder.restoreCallingIdentity(callingId);
8117 return PackageManager.INSTALL_SUCCEEDED;
8120 boolean isUserRestricted(int userId, String restrictionKey) {
8121 Bundle restrictions = sUserManager.getUserRestrictions(userId);
8122 if (restrictions.getBoolean(restrictionKey, false)) {
8123 Log.w(TAG, "User is restricted: " + restrictionKey);
8130 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
8131 mContext.enforceCallingOrSelfPermission(
8132 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8133 "Only package verification agents can verify applications");
8135 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8136 final PackageVerificationResponse response = new PackageVerificationResponse(
8137 verificationCode, Binder.getCallingUid());
8140 mHandler.sendMessage(msg);
8144 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
8145 long millisecondsToDelay) {
8146 mContext.enforceCallingOrSelfPermission(
8147 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8148 "Only package verification agents can extend verification timeouts");
8150 final PackageVerificationState state = mPendingVerification.get(id);
8151 final PackageVerificationResponse response = new PackageVerificationResponse(
8152 verificationCodeAtTimeout, Binder.getCallingUid());
8154 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
8155 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
8157 if (millisecondsToDelay < 0) {
8158 millisecondsToDelay = 0;
8160 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
8161 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
8162 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
8165 if ((state != null) && !state.timeoutExtended()) {
8166 state.extendTimeout();
8168 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8171 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
8175 private void broadcastPackageVerified(int verificationId, Uri packageUri,
8176 int verificationCode, UserHandle user) {
8177 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
8178 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
8179 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8180 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8181 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
8183 mContext.sendBroadcastAsUser(intent, user,
8184 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
8187 private ComponentName matchComponentForVerifier(String packageName,
8188 List<ResolveInfo> receivers) {
8189 ActivityInfo targetReceiver = null;
8191 final int NR = receivers.size();
8192 for (int i = 0; i < NR; i++) {
8193 final ResolveInfo info = receivers.get(i);
8194 if (info.activityInfo == null) {
8198 if (packageName.equals(info.activityInfo.packageName)) {
8199 targetReceiver = info.activityInfo;
8204 if (targetReceiver == null) {
8208 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
8211 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
8212 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
8213 if (pkgInfo.verifiers.length == 0) {
8217 final int N = pkgInfo.verifiers.length;
8218 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
8219 for (int i = 0; i < N; i++) {
8220 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
8222 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
8228 final int verifierUid = getUidForVerifier(verifierInfo);
8229 if (verifierUid == -1) {
8234 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
8235 + " with the correct signature");
8237 sufficientVerifiers.add(comp);
8238 verificationState.addSufficientVerifier(verifierUid);
8241 return sufficientVerifiers;
8244 private int getUidForVerifier(VerifierInfo verifierInfo) {
8245 synchronized (mPackages) {
8246 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
8249 } else if (pkg.mSignatures.length != 1) {
8250 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8251 + " has more than one signature; ignoring");
8256 * If the public key of the package's signature does not match
8257 * our expected public key, then this is a different package and
8261 final byte[] expectedPublicKey;
8263 final Signature verifierSig = pkg.mSignatures[0];
8264 final PublicKey publicKey = verifierSig.getPublicKey();
8265 expectedPublicKey = publicKey.getEncoded();
8266 } catch (CertificateException e) {
8270 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
8272 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
8273 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8274 + " does not have the expected public key; ignoring");
8278 return pkg.applicationInfo.uid;
8283 public void finishPackageInstall(int token) {
8284 enforceSystemOrRoot("Only the system is allowed to finish installs");
8286 if (DEBUG_INSTALL) {
8287 Slog.v(TAG, "BM finishing package install for " + token);
8290 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8291 mHandler.sendMessage(msg);
8295 * Get the verification agent timeout.
8297 * @return verification timeout in milliseconds
8299 private long getVerificationTimeout() {
8300 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8301 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
8302 DEFAULT_VERIFICATION_TIMEOUT);
8306 * Get the default verification agent response code.
8308 * @return default verification response code
8310 private int getDefaultVerificationResponse() {
8311 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8312 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
8313 DEFAULT_VERIFICATION_RESPONSE);
8317 * Check whether or not package verification has been enabled.
8319 * @return true if verification should be performed
8321 private boolean isVerificationEnabled(int userId, int installFlags) {
8322 if (!DEFAULT_VERIFY_ENABLE) {
8326 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
8328 // Check if installing from ADB
8329 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
8330 // Do not run verification in a test harness environment
8331 if (ActivityManager.isRunningInTestHarness()) {
8334 if (ensureVerifyAppsEnabled) {
8337 // Check if the developer does not want package verification for ADB installs
8338 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8339 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
8344 if (ensureVerifyAppsEnabled) {
8348 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8349 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
8353 * Get the "allow unknown sources" setting.
8355 * @return the current "allow unknown sources" setting
8357 private int getUnknownSourcesSettings() {
8358 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8359 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
8364 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
8365 final int uid = Binder.getCallingUid();
8367 synchronized (mPackages) {
8368 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
8369 if (targetPackageSetting == null) {
8370 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
8373 PackageSetting installerPackageSetting;
8374 if (installerPackageName != null) {
8375 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
8376 if (installerPackageSetting == null) {
8377 throw new IllegalArgumentException("Unknown installer package: "
8378 + installerPackageName);
8381 installerPackageSetting = null;
8384 Signature[] callerSignature;
8385 Object obj = mSettings.getUserIdLPr(uid);
8387 if (obj instanceof SharedUserSetting) {
8388 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
8389 } else if (obj instanceof PackageSetting) {
8390 callerSignature = ((PackageSetting)obj).signatures.mSignatures;
8392 throw new SecurityException("Bad object " + obj + " for uid " + uid);
8395 throw new SecurityException("Unknown calling uid " + uid);
8398 // Verify: can't set installerPackageName to a package that is
8399 // not signed with the same cert as the caller.
8400 if (installerPackageSetting != null) {
8401 if (compareSignatures(callerSignature,
8402 installerPackageSetting.signatures.mSignatures)
8403 != PackageManager.SIGNATURE_MATCH) {
8404 throw new SecurityException(
8405 "Caller does not have same cert as new installer package "
8406 + installerPackageName);
8410 // Verify: if target already has an installer package, it must
8411 // be signed with the same cert as the caller.
8412 if (targetPackageSetting.installerPackageName != null) {
8413 PackageSetting setting = mSettings.mPackages.get(
8414 targetPackageSetting.installerPackageName);
8415 // If the currently set package isn't valid, then it's always
8416 // okay to change it.
8417 if (setting != null) {
8418 if (compareSignatures(callerSignature,
8419 setting.signatures.mSignatures)
8420 != PackageManager.SIGNATURE_MATCH) {
8421 throw new SecurityException(
8422 "Caller does not have same cert as old installer package "
8423 + targetPackageSetting.installerPackageName);
8429 targetPackageSetting.installerPackageName = installerPackageName;
8430 scheduleWriteSettingsLocked();
8434 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
8435 // Queue up an async operation since the package installation may take a little while.
8436 mHandler.post(new Runnable() {
8438 mHandler.removeCallbacks(this);
8439 // Result object to be returned
8440 PackageInstalledInfo res = new PackageInstalledInfo();
8441 res.returnCode = currentStatus;
8444 res.removedInfo = new PackageRemovedInfo();
8445 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
8446 args.doPreInstall(res.returnCode);
8447 synchronized (mInstallLock) {
8448 installPackageLI(args, res);
8450 args.doPostInstall(res.returnCode, res.uid);
8453 // A restore should be performed at this point if (a) the install
8454 // succeeded, (b) the operation is not an update, and (c) the new
8455 // package has not opted out of backup participation.
8456 final boolean update = res.removedInfo.removedPackage != null;
8457 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
8458 boolean doRestore = !update
8459 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
8461 // Set up the post-install work request bookkeeping. This will be used
8462 // and cleaned up by the post-install event handling regardless of whether
8463 // there's a restore pass performed. Token values are >= 1.
8465 if (mNextInstallToken < 0) mNextInstallToken = 1;
8466 token = mNextInstallToken++;
8468 PostInstallData data = new PostInstallData(args, res);
8469 mRunningInstalls.put(token, data);
8470 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
8472 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
8473 // Pass responsibility to the Backup Manager. It will perform a
8474 // restore if appropriate, then pass responsibility back to the
8475 // Package Manager to run the post-install observer callbacks
8477 IBackupManager bm = IBackupManager.Stub.asInterface(
8478 ServiceManager.getService(Context.BACKUP_SERVICE));
8480 if (DEBUG_INSTALL) Log.v(TAG, "token " + token
8481 + " to BM for possible restore");
8483 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
8484 } catch (RemoteException e) {
8485 // can't happen; the backup manager is local
8486 } catch (Exception e) {
8487 Slog.e(TAG, "Exception trying to enqueue restore", e);
8491 Slog.e(TAG, "Backup Manager not found!");
8497 // No restore possible, or the Backup Manager was mysteriously not
8498 // available -- just fire the post-install work request directly.
8499 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
8500 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8501 mHandler.sendMessage(msg);
8507 private abstract class HandlerParams {
8508 private static final int MAX_RETRIES = 4;
8511 * Number of times startCopy() has been attempted and had a non-fatal
8514 private int mRetries = 0;
8516 /** User handle for the user requesting the information or installation. */
8517 private final UserHandle mUser;
8519 HandlerParams(UserHandle user) {
8523 UserHandle getUser() {
8527 final boolean startCopy() {
8530 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
8532 if (++mRetries > MAX_RETRIES) {
8533 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
8534 mHandler.sendEmptyMessage(MCS_GIVE_UP);
8535 handleServiceError();
8541 } catch (RemoteException e) {
8542 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
8543 mHandler.sendEmptyMessage(MCS_RECONNECT);
8550 final void serviceError() {
8551 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
8552 handleServiceError();
8556 abstract void handleStartCopy() throws RemoteException;
8557 abstract void handleServiceError();
8558 abstract void handleReturnCode();
8561 class MeasureParams extends HandlerParams {
8562 private final PackageStats mStats;
8563 private boolean mSuccess;
8565 private final IPackageStatsObserver mObserver;
8567 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
8568 super(new UserHandle(stats.userHandle));
8569 mObserver = observer;
8574 public String toString() {
8575 return "MeasureParams{"
8576 + Integer.toHexString(System.identityHashCode(this))
8577 + " " + mStats.packageName + "}";
8581 void handleStartCopy() throws RemoteException {
8582 synchronized (mInstallLock) {
8583 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
8587 final boolean mounted;
8588 if (Environment.isExternalStorageEmulated()) {
8591 final String status = Environment.getExternalStorageState();
8592 mounted = (Environment.MEDIA_MOUNTED.equals(status)
8593 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
8597 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
8599 mStats.externalCacheSize = calculateDirectorySize(mContainerService,
8600 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
8602 mStats.externalDataSize = calculateDirectorySize(mContainerService,
8603 userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
8605 // Always subtract cache size, since it's a subdirectory
8606 mStats.externalDataSize -= mStats.externalCacheSize;
8608 mStats.externalMediaSize = calculateDirectorySize(mContainerService,
8609 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
8611 mStats.externalObbSize = calculateDirectorySize(mContainerService,
8612 userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
8618 void handleReturnCode() {
8619 if (mObserver != null) {
8621 mObserver.onGetStatsCompleted(mStats, mSuccess);
8622 } catch (RemoteException e) {
8623 Slog.i(TAG, "Observer no longer exists.");
8629 void handleServiceError() {
8630 Slog.e(TAG, "Could not measure application " + mStats.packageName
8631 + " external storage");
8635 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
8636 throws RemoteException {
8638 for (File path : paths) {
8639 result += mcs.calculateDirectorySize(path.getAbsolutePath());
8644 private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
8645 for (File path : paths) {
8647 mcs.clearDirectory(path.getAbsolutePath());
8648 } catch (RemoteException e) {
8653 static class OriginInfo {
8655 * Location where install is coming from, before it has been
8656 * copied/renamed into place. This could be a single monolithic APK
8657 * file, or a cluster directory. This location may be untrusted.
8663 * Flag indicating that {@link #file} or {@link #cid} has already been
8664 * staged, meaning downstream users don't need to defensively copy the
8667 final boolean staged;
8670 * Flag indicating that {@link #file} or {@link #cid} is an already
8671 * installed app that is being moved.
8673 final boolean existing;
8675 final String resolvedPath;
8676 final File resolvedFile;
8678 static OriginInfo fromNothing() {
8679 return new OriginInfo(null, null, false, false);
8682 static OriginInfo fromUntrustedFile(File file) {
8683 return new OriginInfo(file, null, false, false);
8686 static OriginInfo fromExistingFile(File file) {
8687 return new OriginInfo(file, null, false, true);
8690 static OriginInfo fromStagedFile(File file) {
8691 return new OriginInfo(file, null, true, false);
8694 static OriginInfo fromStagedContainer(String cid) {
8695 return new OriginInfo(null, cid, true, false);
8698 private OriginInfo(File file, String cid, boolean staged, boolean existing) {
8701 this.staged = staged;
8702 this.existing = existing;
8705 resolvedPath = PackageHelper.getSdDir(cid);
8706 resolvedFile = new File(resolvedPath);
8707 } else if (file != null) {
8708 resolvedPath = file.getAbsolutePath();
8709 resolvedFile = file;
8711 resolvedPath = null;
8712 resolvedFile = null;
8717 class InstallParams extends HandlerParams {
8718 final OriginInfo origin;
8719 final IPackageInstallObserver2 observer;
8721 final String installerPackageName;
8722 final VerificationParams verificationParams;
8723 private InstallArgs mArgs;
8725 final String packageAbiOverride;
8727 InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
8728 String installerPackageName, VerificationParams verificationParams, UserHandle user,
8729 String packageAbiOverride) {
8731 this.origin = origin;
8732 this.observer = observer;
8733 this.installFlags = installFlags;
8734 this.installerPackageName = installerPackageName;
8735 this.verificationParams = verificationParams;
8736 this.packageAbiOverride = packageAbiOverride;
8740 public String toString() {
8741 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
8742 + " file=" + origin.file + " cid=" + origin.cid + "}";
8745 public ManifestDigest getManifestDigest() {
8746 if (verificationParams == null) {
8749 return verificationParams.getManifestDigest();
8752 private int installLocationPolicy(PackageInfoLite pkgLite) {
8753 String packageName = pkgLite.packageName;
8754 int installLocation = pkgLite.installLocation;
8755 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8757 synchronized (mPackages) {
8758 PackageParser.Package pkg = mPackages.get(packageName);
8760 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
8761 // Check for downgrading.
8762 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
8763 if (pkgLite.versionCode < pkg.mVersionCode) {
8764 Slog.w(TAG, "Can't install update of " + packageName
8765 + " update version " + pkgLite.versionCode
8766 + " is older than installed version "
8767 + pkg.mVersionCode);
8768 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
8771 // Check for updated system application.
8772 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8774 Slog.w(TAG, "Cannot install update to system app on sdcard");
8775 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
8777 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8780 // Install flag overrides everything.
8781 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8783 // If current upgrade specifies particular preference
8784 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
8785 // Application explicitly specified internal.
8786 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8787 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
8788 // App explictly prefers external. Let policy decide
8790 // Prefer previous location
8791 if (isExternal(pkg)) {
8792 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8794 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8798 // Invalid install. Return error code
8799 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
8803 // All the special cases have been taken care of.
8804 // Return result based on recommended install location.
8806 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8808 return pkgLite.recommendedInstallLocation;
8812 * Invoke remote method to get package information and install
8813 * location values. Override install location based on default
8814 * policy if needed and then create install arguments based
8815 * on the install location.
8817 public void handleStartCopy() throws RemoteException {
8818 int ret = PackageManager.INSTALL_SUCCEEDED;
8820 // If we're already staged, we've firmly committed to an install location
8821 if (origin.staged) {
8822 if (origin.file != null) {
8823 installFlags |= PackageManager.INSTALL_INTERNAL;
8824 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8825 } else if (origin.cid != null) {
8826 installFlags |= PackageManager.INSTALL_EXTERNAL;
8827 installFlags &= ~PackageManager.INSTALL_INTERNAL;
8829 throw new IllegalStateException("Invalid stage location");
8833 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8834 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
8836 PackageInfoLite pkgLite = null;
8838 if (onInt && onSd) {
8839 // Check if both bits are set.
8840 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
8841 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8843 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
8844 packageAbiOverride);
8847 * If we have too little free space, try to free cache
8850 if (!origin.staged && pkgLite.recommendedInstallLocation
8851 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8852 // TODO: focus freeing disk space on the target device
8853 final StorageManager storage = StorageManager.from(mContext);
8854 final long lowThreshold = storage.getStorageLowBytes(
8855 Environment.getDataDirectory());
8857 final long sizeBytes = mContainerService.calculateInstalledSize(
8858 origin.resolvedPath, isForwardLocked(), packageAbiOverride);
8860 if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
8861 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
8862 installFlags, packageAbiOverride);
8866 * The cache free must have deleted the file we
8867 * downloaded to install.
8869 * TODO: fix the "freeCache" call to not delete
8870 * the file we care about.
8872 if (pkgLite.recommendedInstallLocation
8873 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8874 pkgLite.recommendedInstallLocation
8875 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
8880 if (ret == PackageManager.INSTALL_SUCCEEDED) {
8881 int loc = pkgLite.recommendedInstallLocation;
8882 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
8883 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8884 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
8885 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8886 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8887 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8888 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
8889 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
8890 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8891 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
8892 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
8893 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
8895 // Override with defaults if needed.
8896 loc = installLocationPolicy(pkgLite);
8897 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
8898 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
8899 } else if (!onSd && !onInt) {
8900 // Override install location with flags
8901 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
8902 // Set the flag to install on external media.
8903 installFlags |= PackageManager.INSTALL_EXTERNAL;
8904 installFlags &= ~PackageManager.INSTALL_INTERNAL;
8906 // Make sure the flag for installing on external
8908 installFlags |= PackageManager.INSTALL_INTERNAL;
8909 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8915 final InstallArgs args = createInstallArgs(this);
8918 if (ret == PackageManager.INSTALL_SUCCEEDED) {
8920 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
8921 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
8923 int userIdentifier = getUser().getIdentifier();
8924 if (userIdentifier == UserHandle.USER_ALL
8925 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
8926 userIdentifier = UserHandle.USER_OWNER;
8930 * Determine if we have any installed package verifiers. If we
8931 * do, then we'll defer to them to verify the packages.
8933 final int requiredUid = mRequiredVerifierPackage == null ? -1
8934 : getPackageUid(mRequiredVerifierPackage, userIdentifier);
8935 if (!origin.existing && requiredUid != -1
8936 && isVerificationEnabled(userIdentifier, installFlags)) {
8937 final Intent verification = new Intent(
8938 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
8939 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
8941 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8943 final List<ResolveInfo> receivers = queryIntentReceivers(verification,
8944 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
8945 0 /* TODO: Which userId? */);
8948 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
8949 + verification.toString() + " with " + pkgLite.verifiers.length
8950 + " optional verifiers");
8953 final int verificationId = mPendingVerificationToken++;
8955 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8957 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
8958 installerPackageName);
8960 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
8963 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
8964 pkgLite.packageName);
8966 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
8967 pkgLite.versionCode);
8969 if (verificationParams != null) {
8970 if (verificationParams.getVerificationURI() != null) {
8971 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
8972 verificationParams.getVerificationURI());
8974 if (verificationParams.getOriginatingURI() != null) {
8975 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
8976 verificationParams.getOriginatingURI());
8978 if (verificationParams.getReferrer() != null) {
8979 verification.putExtra(Intent.EXTRA_REFERRER,
8980 verificationParams.getReferrer());
8982 if (verificationParams.getOriginatingUid() >= 0) {
8983 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
8984 verificationParams.getOriginatingUid());
8986 if (verificationParams.getInstallerUid() >= 0) {
8987 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
8988 verificationParams.getInstallerUid());
8992 final PackageVerificationState verificationState = new PackageVerificationState(
8995 mPendingVerification.append(verificationId, verificationState);
8997 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
8998 receivers, verificationState);
9001 * If any sufficient verifiers were listed in the package
9002 * manifest, attempt to ask them.
9004 if (sufficientVerifiers != null) {
9005 final int N = sufficientVerifiers.size();
9007 Slog.i(TAG, "Additional verifiers required, but none installed.");
9008 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
9010 for (int i = 0; i < N; i++) {
9011 final ComponentName verifierComponent = sufficientVerifiers.get(i);
9013 final Intent sufficientIntent = new Intent(verification);
9014 sufficientIntent.setComponent(verifierComponent);
9016 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
9021 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
9022 mRequiredVerifierPackage, receivers);
9023 if (ret == PackageManager.INSTALL_SUCCEEDED
9024 && mRequiredVerifierPackage != null) {
9026 * Send the intent to the required verification agent,
9027 * but only start the verification timeout after the
9028 * target BroadcastReceivers have run.
9030 verification.setComponent(requiredVerifierComponent);
9031 mContext.sendOrderedBroadcastAsUser(verification, getUser(),
9032 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9033 new BroadcastReceiver() {
9035 public void onReceive(Context context, Intent intent) {
9036 final Message msg = mHandler
9037 .obtainMessage(CHECK_PENDING_VERIFICATION);
9038 msg.arg1 = verificationId;
9039 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
9041 }, null, 0, null, null);
9044 * We don't want the copy to proceed until verification
9045 * succeeds, so null out this field.
9051 * No package verification is enabled, so immediately start
9052 * the remote call to initiate copy using temporary file.
9054 ret = args.copyApk(mContainerService, true);
9062 void handleReturnCode() {
9063 // If mArgs is null, then MCS couldn't be reached. When it
9064 // reconnects, it will try again to install. At that point, this
9066 if (mArgs != null) {
9067 processPendingInstall(mArgs, mRet);
9072 void handleServiceError() {
9073 mArgs = createInstallArgs(this);
9074 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9077 public boolean isForwardLocked() {
9078 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9083 * Used during creation of InstallArgs
9085 * @param installFlags package installation flags
9086 * @return true if should be installed on external storage
9088 private static boolean installOnSd(int installFlags) {
9089 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
9092 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
9099 * Used during creation of InstallArgs
9101 * @param installFlags package installation flags
9102 * @return true if should be installed as forward locked
9104 private static boolean installForwardLocked(int installFlags) {
9105 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9108 private InstallArgs createInstallArgs(InstallParams params) {
9109 if (installOnSd(params.installFlags) || params.isForwardLocked()) {
9110 return new AsecInstallArgs(params);
9112 return new FileInstallArgs(params);
9117 * Create args that describe an existing installed package. Typically used
9118 * when cleaning up old installs, or used as a move source.
9120 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
9121 String resourcePath, String nativeLibraryRoot, String[] instructionSets) {
9122 final boolean isInAsec;
9123 if (installOnSd(installFlags)) {
9124 /* Apps on SD card are always in ASEC containers. */
9126 } else if (installForwardLocked(installFlags)
9127 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
9129 * Forward-locked apps are only in ASEC containers if they're the
9138 return new AsecInstallArgs(codePath, instructionSets,
9139 installOnSd(installFlags), installForwardLocked(installFlags));
9141 return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
9146 static abstract class InstallArgs {
9147 /** @see InstallParams#origin */
9148 final OriginInfo origin;
9150 final IPackageInstallObserver2 observer;
9151 // Always refers to PackageManager flags only
9152 final int installFlags;
9153 final String installerPackageName;
9154 final ManifestDigest manifestDigest;
9155 final UserHandle user;
9156 final String abiOverride;
9158 // The list of instruction sets supported by this app. This is currently
9159 // only used during the rmdex() phase to clean up resources. We can get rid of this
9160 // if we move dex files under the common app path.
9161 /* nullable */ String[] instructionSets;
9163 InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
9164 String installerPackageName, ManifestDigest manifestDigest, UserHandle user,
9165 String[] instructionSets, String abiOverride) {
9166 this.origin = origin;
9167 this.installFlags = installFlags;
9168 this.observer = observer;
9169 this.installerPackageName = installerPackageName;
9170 this.manifestDigest = manifestDigest;
9172 this.instructionSets = instructionSets;
9173 this.abiOverride = abiOverride;
9176 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
9177 abstract int doPreInstall(int status);
9180 * Rename package into final resting place. All paths on the given
9181 * scanned package should be updated to reflect the rename.
9183 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
9184 abstract int doPostInstall(int status, int uid);
9186 /** @see PackageSettingBase#codePathString */
9187 abstract String getCodePath();
9188 /** @see PackageSettingBase#resourcePathString */
9189 abstract String getResourcePath();
9190 abstract String getLegacyNativeLibraryPath();
9192 // Need installer lock especially for dex file removal.
9193 abstract void cleanUpResourcesLI();
9194 abstract boolean doPostDeleteLI(boolean delete);
9195 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
9198 * Called before the source arguments are copied. This is used mostly
9199 * for MoveParams when it needs to read the source file to put it in the
9203 return PackageManager.INSTALL_SUCCEEDED;
9207 * Called after the source arguments are copied. This is used mostly for
9208 * MoveParams when it needs to read the source file to put it in the
9213 int doPostCopy(int uid) {
9214 return PackageManager.INSTALL_SUCCEEDED;
9217 protected boolean isFwdLocked() {
9218 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9221 protected boolean isExternal() {
9222 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
9225 UserHandle getUser() {
9231 * Logic to handle installation of non-ASEC applications, including copying
9232 * and renaming logic.
9234 class FileInstallArgs extends InstallArgs {
9235 private File codeFile;
9236 private File resourceFile;
9237 private File legacyNativeLibraryPath;
9239 // Example topology:
9240 // /data/app/com.example/base.apk
9241 // /data/app/com.example/split_foo.apk
9242 // /data/app/com.example/lib/arm/libfoo.so
9243 // /data/app/com.example/lib/arm64/libfoo.so
9244 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
9247 FileInstallArgs(InstallParams params) {
9248 super(params.origin, params.observer, params.installFlags,
9249 params.installerPackageName, params.getManifestDigest(), params.getUser(),
9250 null /* instruction sets */, params.packageAbiOverride);
9251 if (isFwdLocked()) {
9252 throw new IllegalArgumentException("Forward locking only supported in ASEC");
9256 /** Existing install */
9257 FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath,
9258 String[] instructionSets) {
9259 super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null);
9260 this.codeFile = (codePath != null) ? new File(codePath) : null;
9261 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
9262 this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ?
9263 new File(legacyNativeLibraryPath) : null;
9266 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9267 final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(),
9268 isFwdLocked(), abiOverride);
9270 final StorageManager storage = StorageManager.from(mContext);
9271 return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
9274 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9275 if (origin.staged) {
9276 Slog.d(TAG, origin.file + " already staged; skipping copy");
9277 codeFile = origin.file;
9278 resourceFile = origin.file;
9279 return PackageManager.INSTALL_SUCCEEDED;
9283 final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
9285 resourceFile = tempDir;
9286 } catch (IOException e) {
9287 Slog.w(TAG, "Failed to create copy file: " + e);
9288 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9291 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
9293 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
9294 if (!FileUtils.isValidExtFilename(name)) {
9295 throw new IllegalArgumentException("Invalid filename: " + name);
9298 final File file = new File(codeFile, name);
9299 final FileDescriptor fd = Os.open(file.getAbsolutePath(),
9300 O_RDWR | O_CREAT, 0644);
9301 Os.chmod(file.getAbsolutePath(), 0644);
9302 return new ParcelFileDescriptor(fd);
9303 } catch (ErrnoException e) {
9304 throw new RemoteException("Failed to open: " + e.getMessage());
9309 int ret = PackageManager.INSTALL_SUCCEEDED;
9310 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
9311 if (ret != PackageManager.INSTALL_SUCCEEDED) {
9312 Slog.e(TAG, "Failed to copy package");
9316 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
9317 NativeLibraryHelper.Handle handle = null;
9319 handle = NativeLibraryHelper.Handle.create(codeFile);
9320 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
9322 } catch (IOException e) {
9323 Slog.e(TAG, "Copying native libraries failed", e);
9324 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9326 IoUtils.closeQuietly(handle);
9332 int doPreInstall(int status) {
9333 if (status != PackageManager.INSTALL_SUCCEEDED) {
9339 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9340 if (status != PackageManager.INSTALL_SUCCEEDED) {
9344 final File beforeCodeFile = codeFile;
9345 final File afterCodeFile = getNextCodePath(pkg.packageName);
9347 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
9349 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
9350 } catch (ErrnoException e) {
9351 Slog.d(TAG, "Failed to rename", e);
9355 if (!SELinux.restoreconRecursive(afterCodeFile)) {
9356 Slog.d(TAG, "Failed to restorecon");
9360 // Reflect the rename internally
9361 codeFile = afterCodeFile;
9362 resourceFile = afterCodeFile;
9364 // Reflect the rename in scanned details
9365 pkg.codePath = afterCodeFile.getAbsolutePath();
9366 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9368 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9369 pkg.splitCodePaths);
9371 // Reflect the rename in app info
9372 pkg.applicationInfo.setCodePath(pkg.codePath);
9373 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9374 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9375 pkg.applicationInfo.setResourcePath(pkg.codePath);
9376 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9377 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9383 int doPostInstall(int status, int uid) {
9384 if (status != PackageManager.INSTALL_SUCCEEDED) {
9391 String getCodePath() {
9392 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
9396 String getResourcePath() {
9397 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
9401 String getLegacyNativeLibraryPath() {
9402 return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null;
9405 private boolean cleanUp() {
9406 if (codeFile == null || !codeFile.exists()) {
9410 if (codeFile.isDirectory()) {
9411 FileUtils.deleteContents(codeFile);
9415 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
9416 resourceFile.delete();
9419 if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) {
9420 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) {
9421 Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath);
9423 legacyNativeLibraryPath.delete();
9429 void cleanUpResourcesLI() {
9430 // Try enumerating all code paths before deleting
9431 List<String> allCodePaths = Collections.EMPTY_LIST;
9432 if (codeFile != null && codeFile.exists()) {
9434 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9435 allCodePaths = pkg.getAllCodePaths();
9436 } catch (PackageParserException e) {
9437 // Ignored; we tried our best
9443 if (!allCodePaths.isEmpty()) {
9444 if (instructionSets == null) {
9445 throw new IllegalStateException("instructionSet == null");
9447 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9448 for (String codePath : allCodePaths) {
9449 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9450 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9452 Slog.w(TAG, "Couldn't remove dex file for package: "
9453 + " at location " + codePath + ", retcode=" + retCode);
9454 // we don't consider this to be a failure of the core package deletion
9461 boolean doPostDeleteLI(boolean delete) {
9462 // XXX err, shouldn't we respect the delete flag?
9463 cleanUpResourcesLI();
9468 private boolean isAsecExternal(String cid) {
9469 final String asecPath = PackageHelper.getSdFilesystem(cid);
9470 return !asecPath.startsWith(mAsecInternalPath);
9473 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
9474 PackageManagerException {
9476 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
9477 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
9478 throw new PackageManagerException(copyRet, message);
9484 * Extract the MountService "container ID" from the full code path of an
9487 static String cidFromCodePath(String fullCodePath) {
9488 int eidx = fullCodePath.lastIndexOf("/");
9489 String subStr1 = fullCodePath.substring(0, eidx);
9490 int sidx = subStr1.lastIndexOf("/");
9491 return subStr1.substring(sidx+1, eidx);
9495 * Logic to handle installation of ASEC applications, including copying and
9498 class AsecInstallArgs extends InstallArgs {
9499 static final String RES_FILE_NAME = "pkg.apk";
9500 static final String PUBLIC_RES_FILE_NAME = "res.zip";
9504 String resourcePath;
9505 String legacyNativeLibraryDir;
9508 AsecInstallArgs(InstallParams params) {
9509 super(params.origin, params.observer, params.installFlags,
9510 params.installerPackageName, params.getManifestDigest(),
9511 params.getUser(), null /* instruction sets */,
9512 params.packageAbiOverride);
9515 /** Existing install */
9516 AsecInstallArgs(String fullCodePath, String[] instructionSets,
9517 boolean isExternal, boolean isForwardLocked) {
9518 super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0)
9519 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9520 instructionSets, null);
9521 // Hackily pretend we're still looking at a full code path
9522 if (!fullCodePath.endsWith(RES_FILE_NAME)) {
9523 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
9526 // Extract cid from fullCodePath
9527 int eidx = fullCodePath.lastIndexOf("/");
9528 String subStr1 = fullCodePath.substring(0, eidx);
9529 int sidx = subStr1.lastIndexOf("/");
9530 cid = subStr1.substring(sidx+1, eidx);
9531 setMountPath(subStr1);
9534 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
9535 super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
9536 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9537 instructionSets, null);
9539 setMountPath(PackageHelper.getSdDir(cid));
9542 void createCopyFile() {
9543 cid = mInstallerService.allocateExternalStageCidLegacy();
9546 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9547 final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
9552 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
9554 target = Environment.getDataDirectory();
9557 final StorageManager storage = StorageManager.from(mContext);
9558 return (sizeBytes <= storage.getStorageBytesUntilLow(target));
9561 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9562 if (origin.staged) {
9563 Slog.d(TAG, origin.cid + " already staged; skipping copy");
9565 setMountPath(PackageHelper.getSdDir(cid));
9566 return PackageManager.INSTALL_SUCCEEDED;
9573 * Pre-emptively destroy the container since it's destroyed if
9574 * copying fails due to it existing anyway.
9576 PackageHelper.destroySdDir(cid);
9579 final String newMountPath = imcs.copyPackageToContainer(
9580 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
9581 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
9583 if (newMountPath != null) {
9584 setMountPath(newMountPath);
9585 return PackageManager.INSTALL_SUCCEEDED;
9587 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9592 String getCodePath() {
9597 String getResourcePath() {
9598 return resourcePath;
9602 String getLegacyNativeLibraryPath() {
9603 return legacyNativeLibraryDir;
9606 int doPreInstall(int status) {
9607 if (status != PackageManager.INSTALL_SUCCEEDED) {
9608 // Destroy container
9609 PackageHelper.destroySdDir(cid);
9611 boolean mounted = PackageHelper.isContainerMounted(cid);
9613 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
9614 Process.SYSTEM_UID);
9615 if (newMountPath != null) {
9616 setMountPath(newMountPath);
9618 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9625 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9626 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
9627 String newMountPath = null;
9628 if (PackageHelper.isContainerMounted(cid)) {
9629 // Unmount the container
9630 if (!PackageHelper.unMountSdDir(cid)) {
9631 Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
9635 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9636 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
9637 " which might be stale. Will try to clean up.");
9638 // Clean up the stale container and proceed to recreate.
9639 if (!PackageHelper.destroySdDir(newCacheId)) {
9640 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
9643 // Successfully cleaned up stale container. Try to rename again.
9644 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9645 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
9646 + " inspite of cleaning it up.");
9650 if (!PackageHelper.isContainerMounted(newCacheId)) {
9651 Slog.w(TAG, "Mounting container " + newCacheId);
9652 newMountPath = PackageHelper.mountSdDir(newCacheId,
9653 getEncryptKey(), Process.SYSTEM_UID);
9655 newMountPath = PackageHelper.getSdDir(newCacheId);
9657 if (newMountPath == null) {
9658 Slog.w(TAG, "Failed to get cache path for " + newCacheId);
9661 Log.i(TAG, "Succesfully renamed " + cid +
9662 " to " + newCacheId +
9663 " at new path: " + newMountPath);
9666 final File beforeCodeFile = new File(packagePath);
9667 setMountPath(newMountPath);
9668 final File afterCodeFile = new File(packagePath);
9670 // Reflect the rename in scanned details
9671 pkg.codePath = afterCodeFile.getAbsolutePath();
9672 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9674 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9675 pkg.splitCodePaths);
9677 // Reflect the rename in app info
9678 pkg.applicationInfo.setCodePath(pkg.codePath);
9679 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9680 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9681 pkg.applicationInfo.setResourcePath(pkg.codePath);
9682 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9683 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9688 private void setMountPath(String mountPath) {
9689 final File mountFile = new File(mountPath);
9691 final File monolithicFile = new File(mountFile, RES_FILE_NAME);
9692 if (monolithicFile.exists()) {
9693 packagePath = monolithicFile.getAbsolutePath();
9694 if (isFwdLocked()) {
9695 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
9697 resourcePath = packagePath;
9700 packagePath = mountFile.getAbsolutePath();
9701 resourcePath = packagePath;
9704 legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
9707 int doPostInstall(int status, int uid) {
9708 if (status != PackageManager.INSTALL_SUCCEEDED) {
9711 final int groupOwner;
9712 final String protectedFile;
9713 if (isFwdLocked()) {
9714 groupOwner = UserHandle.getSharedAppGid(uid);
9715 protectedFile = RES_FILE_NAME;
9718 protectedFile = null;
9721 if (uid < Process.FIRST_APPLICATION_UID
9722 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
9723 Slog.e(TAG, "Failed to finalize " + cid);
9724 PackageHelper.destroySdDir(cid);
9725 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9728 boolean mounted = PackageHelper.isContainerMounted(cid);
9730 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
9736 private void cleanUp() {
9737 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
9739 // Destroy secure container
9740 PackageHelper.destroySdDir(cid);
9743 private List<String> getAllCodePaths() {
9744 final File codeFile = new File(getCodePath());
9745 if (codeFile != null && codeFile.exists()) {
9747 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9748 return pkg.getAllCodePaths();
9749 } catch (PackageParserException e) {
9750 // Ignored; we tried our best
9753 return Collections.EMPTY_LIST;
9756 void cleanUpResourcesLI() {
9757 // Enumerate all code paths before deleting
9758 cleanUpResourcesLI(getAllCodePaths());
9761 private void cleanUpResourcesLI(List<String> allCodePaths) {
9764 if (!allCodePaths.isEmpty()) {
9765 if (instructionSets == null) {
9766 throw new IllegalStateException("instructionSet == null");
9768 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9769 for (String codePath : allCodePaths) {
9770 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9771 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9773 Slog.w(TAG, "Couldn't remove dex file for package: "
9774 + " at location " + codePath + ", retcode=" + retCode);
9775 // we don't consider this to be a failure of the core package deletion
9782 boolean matchContainer(String app) {
9783 if (cid.startsWith(app)) {
9789 String getPackageName() {
9790 return getAsecPackageName(cid);
9793 boolean doPostDeleteLI(boolean delete) {
9794 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
9795 final List<String> allCodePaths = getAllCodePaths();
9796 boolean mounted = PackageHelper.isContainerMounted(cid);
9799 if (PackageHelper.unMountSdDir(cid)) {
9803 if (!mounted && delete) {
9804 cleanUpResourcesLI(allCodePaths);
9811 if (isFwdLocked()) {
9812 if (!PackageHelper.fixSdPermissions(cid,
9813 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
9814 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9818 return PackageManager.INSTALL_SUCCEEDED;
9822 int doPostCopy(int uid) {
9823 if (isFwdLocked()) {
9824 if (uid < Process.FIRST_APPLICATION_UID
9825 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
9827 Slog.e(TAG, "Failed to finalize " + cid);
9828 PackageHelper.destroySdDir(cid);
9829 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9833 return PackageManager.INSTALL_SUCCEEDED;
9837 static String getAsecPackageName(String packageCid) {
9838 int idx = packageCid.lastIndexOf("-");
9842 return packageCid.substring(0, idx);
9845 // Utility method used to create code paths based on package name and available index.
9846 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
9849 // Fall back to default value of idx=1 if prefix is not
9850 // part of oldCodePath
9851 if (oldCodePath != null) {
9852 String subStr = oldCodePath;
9853 // Drop the suffix right away
9854 if (suffix != null && subStr.endsWith(suffix)) {
9855 subStr = subStr.substring(0, subStr.length() - suffix.length());
9857 // If oldCodePath already contains prefix find out the
9858 // ending index to either increment or decrement.
9859 int sidx = subStr.lastIndexOf(prefix);
9861 subStr = subStr.substring(sidx + prefix.length());
9862 if (subStr != null) {
9863 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
9864 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
9867 idx = Integer.parseInt(subStr);
9873 } catch(NumberFormatException e) {
9878 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
9879 return prefix + idxStr;
9882 private File getNextCodePath(String packageName) {
9886 result = new File(mAppInstallDir, packageName + "-" + suffix);
9888 } while (result.exists());
9892 // Utility method used to ignore ADD/REMOVE events
9893 // by directory observer.
9894 private static boolean ignoreCodePath(String fullPathStr) {
9895 String apkName = deriveCodePathName(fullPathStr);
9896 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
9897 if (idx != -1 && ((idx+1) < apkName.length())) {
9898 // Make sure the package ends with a numeral
9899 String version = apkName.substring(idx+1);
9901 Integer.parseInt(version);
9903 } catch (NumberFormatException e) {}
9908 // Utility method that returns the relative package path with respect
9909 // to the installation directory. Like say for /data/data/com.test-1.apk
9910 // string com.test-1 is returned.
9911 static String deriveCodePathName(String codePath) {
9912 if (codePath == null) {
9915 final File codeFile = new File(codePath);
9916 final String name = codeFile.getName();
9917 if (codeFile.isDirectory()) {
9919 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
9920 final int lastDot = name.lastIndexOf('.');
9921 return name.substring(0, lastDot);
9923 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
9928 class PackageInstalledInfo {
9931 // The set of users that originally had this package installed.
9933 // The set of users that now have this package installed.
9935 PackageParser.Package pkg;
9938 PackageRemovedInfo removedInfo;
9940 public void setError(int code, String msg) {
9946 public void setError(String msg, PackageParserException e) {
9947 returnCode = e.error;
9948 returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9949 Slog.w(TAG, msg, e);
9952 public void setError(String msg, PackageManagerException e) {
9953 returnCode = e.error;
9954 returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9955 Slog.w(TAG, msg, e);
9958 // In some error cases we want to convey more info back to the observer
9960 String origPermission;
9964 * Install a non-existing package.
9966 private void installNewPackageLI(PackageParser.Package pkg,
9967 int parseFlags, int scanFlags, UserHandle user,
9968 String installerPackageName, PackageInstalledInfo res) {
9969 // Remember this for later, in case we need to rollback this install
9970 String pkgName = pkg.packageName;
9972 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
9973 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
9974 synchronized(mPackages) {
9975 if (mSettings.mRenamedPackages.containsKey(pkgName)) {
9976 // A package with the same name is already installed, though
9977 // it has been renamed to an older name. The package we
9978 // are trying to install should be installed as an update to
9979 // the existing one, but that has not been requested, so bail.
9980 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9981 + " without first uninstalling package running as "
9982 + mSettings.mRenamedPackages.get(pkgName));
9985 if (mPackages.containsKey(pkgName)) {
9986 // Don't allow installation over an existing package with the same name.
9987 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9988 + " without first uninstalling.");
9994 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
9995 System.currentTimeMillis(), user);
9997 updateSettingsLI(newPackage, installerPackageName, null, null, res);
9998 // delete the partially installed application. the data directory will have to be
9999 // restored if it was already existing
10000 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10001 // remove package from internal structures. Note that we want deletePackageX to
10002 // delete the package data and cache directories that it created in
10003 // scanPackageLocked, unless those directories existed before we even tried to
10005 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
10006 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
10007 res.removedInfo, true);
10010 } catch (PackageManagerException e) {
10011 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10015 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
10016 // Upgrade keysets are being used. Determine if new package has a superset of the
10018 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
10019 KeySetManagerService ksms = mSettings.mKeySetManagerService;
10020 for (int i = 0; i < upgradeKeySets.length; i++) {
10021 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
10022 if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
10029 private void replacePackageLI(PackageParser.Package pkg,
10030 int parseFlags, int scanFlags, UserHandle user,
10031 String installerPackageName, PackageInstalledInfo res) {
10032 PackageParser.Package oldPackage;
10033 String pkgName = pkg.packageName;
10035 boolean[] perUserInstalled;
10037 // First find the old package info and check signatures
10038 synchronized(mPackages) {
10039 oldPackage = mPackages.get(pkgName);
10040 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
10041 PackageSetting ps = mSettings.mPackages.get(pkgName);
10042 if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10043 // default to original signature matching
10044 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
10045 != PackageManager.SIGNATURE_MATCH) {
10046 res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10047 "New package has a different signature: " + pkgName);
10051 if(!checkUpgradeKeySetLP(ps, pkg)) {
10052 res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10053 "New package not signed by keys specified by upgrade-keysets: "
10059 // In case of rollback, remember per-user/profile install state
10060 allUsers = sUserManager.getUserIds();
10061 perUserInstalled = new boolean[allUsers.length];
10062 for (int i = 0; i < allUsers.length; i++) {
10063 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10067 boolean sysPkg = (isSystemApp(oldPackage));
10069 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10070 user, allUsers, perUserInstalled, installerPackageName, res);
10072 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10073 user, allUsers, perUserInstalled, installerPackageName, res);
10077 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
10078 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10079 int[] allUsers, boolean[] perUserInstalled,
10080 String installerPackageName, PackageInstalledInfo res) {
10081 String pkgName = deletedPackage.packageName;
10082 boolean deletedPkg = true;
10083 boolean updatedSettings = false;
10085 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
10087 long origUpdateTime;
10088 if (pkg.mExtras != null) {
10089 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
10091 origUpdateTime = 0;
10094 // First delete the existing package while retaining the data directory
10095 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
10096 res.removedInfo, true)) {
10097 // If the existing package wasn't successfully deleted
10098 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
10099 deletedPkg = false;
10101 // Successfully deleted the old package; proceed with replace.
10103 // If deleted package lived in a container, give users a chance to
10104 // relinquish resources before killing.
10105 if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
10106 if (DEBUG_INSTALL) {
10107 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
10109 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
10110 final ArrayList<String> pkgList = new ArrayList<String>(1);
10111 pkgList.add(deletedPackage.applicationInfo.packageName);
10112 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
10115 deleteCodeCacheDirsLI(pkgName);
10117 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
10118 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
10119 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10120 updatedSettings = true;
10121 } catch (PackageManagerException e) {
10122 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10126 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10127 // remove package from internal structures. Note that we want deletePackageX to
10128 // delete the package data and cache directories that it created in
10129 // scanPackageLocked, unless those directories existed before we even tried to
10131 if(updatedSettings) {
10132 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
10134 pkgName, null, true, allUsers, perUserInstalled,
10135 PackageManager.DELETE_KEEP_DATA,
10136 res.removedInfo, true);
10138 // Since we failed to install the new package we need to restore the old
10139 // package that we deleted.
10141 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
10142 File restoreFile = new File(deletedPackage.codePath);
10143 // Parse old package
10144 boolean oldOnSd = isExternal(deletedPackage);
10145 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
10146 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
10147 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
10148 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
10150 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
10151 } catch (PackageManagerException e) {
10152 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
10156 // Restore of old package succeeded. Update permissions.
10158 synchronized (mPackages) {
10159 updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
10160 UPDATE_PERMISSIONS_ALL);
10161 // can downgrade to reader
10162 mSettings.writeLPr();
10164 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
10169 private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
10170 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10171 int[] allUsers, boolean[] perUserInstalled,
10172 String installerPackageName, PackageInstalledInfo res) {
10173 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
10174 + ", old=" + deletedPackage);
10175 boolean disabledSystem = false;
10176 boolean updatedSettings = false;
10177 parseFlags |= PackageParser.PARSE_IS_SYSTEM;
10178 if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
10179 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10181 String packageName = deletedPackage.packageName;
10182 if (packageName == null) {
10183 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10184 "Attempt to delete null packageName.");
10187 PackageParser.Package oldPkg;
10188 PackageSetting oldPkgSetting;
10190 synchronized (mPackages) {
10191 oldPkg = mPackages.get(packageName);
10192 oldPkgSetting = mSettings.mPackages.get(packageName);
10193 if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
10194 (oldPkgSetting == null)) {
10195 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10196 "Couldn't find package:" + packageName + " information");
10201 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
10203 res.removedInfo.uid = oldPkg.applicationInfo.uid;
10204 res.removedInfo.removedPackage = packageName;
10205 // Remove existing system package
10206 removePackageLI(oldPkgSetting, true);
10208 synchronized (mPackages) {
10209 disabledSystem = mSettings.disableSystemPackageLPw(packageName);
10210 if (!disabledSystem && deletedPackage != null) {
10211 // We didn't need to disable the .apk as a current system package,
10212 // which means we are replacing another update that is already
10213 // installed. We need to make sure to delete the older one's .apk.
10214 res.removedInfo.args = createInstallArgsForExisting(0,
10215 deletedPackage.applicationInfo.getCodePath(),
10216 deletedPackage.applicationInfo.getResourcePath(),
10217 deletedPackage.applicationInfo.nativeLibraryRootDir,
10218 getAppDexInstructionSets(deletedPackage.applicationInfo));
10220 res.removedInfo.args = null;
10224 // Successfully disabled the old package. Now proceed with re-installation
10225 deleteCodeCacheDirsLI(packageName);
10227 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10228 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10230 PackageParser.Package newPackage = null;
10232 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
10233 if (newPackage.mExtras != null) {
10234 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
10235 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
10236 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
10238 // is the update attempting to change shared user? that isn't going to work...
10239 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
10240 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
10241 "Forbidding shared user change from " + oldPkgSetting.sharedUser
10242 + " to " + newPkgSetting.sharedUser);
10243 updatedSettings = true;
10247 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10248 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10249 updatedSettings = true;
10252 } catch (PackageManagerException e) {
10253 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10256 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10257 // Re installation failed. Restore old information
10258 // Remove new pkg information
10259 if (newPackage != null) {
10260 removeInstalledPackageLI(newPackage, true);
10262 // Add back the old system package
10264 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
10265 } catch (PackageManagerException e) {
10266 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
10268 // Restore the old system information in Settings
10269 synchronized (mPackages) {
10270 if (disabledSystem) {
10271 mSettings.enableSystemPackageLPw(packageName);
10273 if (updatedSettings) {
10274 mSettings.setInstallerPackageName(packageName,
10275 oldPkgSetting.installerPackageName);
10277 mSettings.writeLPr();
10282 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
10283 int[] allUsers, boolean[] perUserInstalled,
10284 PackageInstalledInfo res) {
10285 String pkgName = newPackage.packageName;
10286 synchronized (mPackages) {
10287 //write settings. the installStatus will be incomplete at this stage.
10288 //note that the new package setting would have already been
10289 //added to mPackages. It hasn't been persisted yet.
10290 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
10291 mSettings.writeLPr();
10294 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
10296 synchronized (mPackages) {
10297 updatePermissionsLPw(newPackage.packageName, newPackage,
10298 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
10299 ? UPDATE_PERMISSIONS_ALL : 0));
10300 // For system-bundled packages, we assume that installing an upgraded version
10301 // of the package implies that the user actually wants to run that new code,
10302 // so we enable the package.
10303 if (isSystemApp(newPackage)) {
10304 // NB: implicit assumption that system package upgrades apply to all users
10305 if (DEBUG_INSTALL) {
10306 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
10308 PackageSetting ps = mSettings.mPackages.get(pkgName);
10310 if (res.origUsers != null) {
10311 for (int userHandle : res.origUsers) {
10312 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
10313 userHandle, installerPackageName);
10316 // Also convey the prior install/uninstall state
10317 if (allUsers != null && perUserInstalled != null) {
10318 for (int i = 0; i < allUsers.length; i++) {
10319 if (DEBUG_INSTALL) {
10320 Slog.d(TAG, " user " + allUsers[i]
10321 + " => " + perUserInstalled[i]);
10323 ps.setInstalled(perUserInstalled[i], allUsers[i]);
10325 // these install state changes will be persisted in the
10326 // upcoming call to mSettings.writeLPr().
10330 res.name = pkgName;
10331 res.uid = newPackage.applicationInfo.uid;
10332 res.pkg = newPackage;
10333 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
10334 mSettings.setInstallerPackageName(pkgName, installerPackageName);
10335 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10336 //to update install status
10337 mSettings.writeLPr();
10341 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
10342 final int installFlags = args.installFlags;
10343 String installerPackageName = args.installerPackageName;
10344 File tmpPackageFile = new File(args.getCodePath());
10345 boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
10346 boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
10347 boolean replace = false;
10348 final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
10349 // Result object to be returned
10350 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10352 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
10353 // Retrieve PackageSettings and parse package
10354 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
10355 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
10356 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
10357 PackageParser pp = new PackageParser();
10358 pp.setSeparateProcesses(mSeparateProcesses);
10359 pp.setDisplayMetrics(mMetrics);
10361 final PackageParser.Package pkg;
10363 pkg = pp.parsePackage(tmpPackageFile, parseFlags);
10364 } catch (PackageParserException e) {
10365 res.setError("Failed parse during installPackageLI", e);
10369 // Mark that we have an install time CPU ABI override.
10370 pkg.cpuAbiOverride = args.abiOverride;
10372 String pkgName = res.name = pkg.packageName;
10373 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
10374 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
10375 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
10381 pp.collectCertificates(pkg, parseFlags);
10382 pp.collectManifestDigest(pkg);
10383 } catch (PackageParserException e) {
10384 res.setError("Failed collect during installPackageLI", e);
10388 /* If the installer passed in a manifest digest, compare it now. */
10389 if (args.manifestDigest != null) {
10390 if (DEBUG_INSTALL) {
10391 final String parsedManifest = pkg.manifestDigest == null ? "null"
10392 : pkg.manifestDigest.toString();
10393 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
10397 if (!args.manifestDigest.equals(pkg.manifestDigest)) {
10398 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
10401 } else if (DEBUG_INSTALL) {
10402 final String parsedManifest = pkg.manifestDigest == null
10403 ? "null" : pkg.manifestDigest.toString();
10404 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
10407 // Get rid of all references to package scan path via parser.
10409 String oldCodePath = null;
10410 boolean systemApp = false;
10411 synchronized (mPackages) {
10412 // Check whether the newly-scanned package wants to define an already-defined perm
10413 int N = pkg.permissions.size();
10414 for (int i = N-1; i >= 0; i--) {
10415 PackageParser.Permission perm = pkg.permissions.get(i);
10416 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
10418 // If the defining package is signed with our cert, it's okay. This
10419 // also includes the "updating the same package" case, of course.
10420 // "updating same package" could also involve key-rotation.
10421 final boolean sigsOk;
10422 if (!bp.sourcePackage.equals(pkg.packageName)
10423 || !(bp.packageSetting instanceof PackageSetting)
10424 || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
10425 || ((PackageSetting) bp.packageSetting).sharedUser != null) {
10426 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
10427 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
10429 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
10432 // If the owning package is the system itself, we log but allow
10433 // install to proceed; we fail the install on all other permission
10435 if (!bp.sourcePackage.equals("android")) {
10436 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
10437 + pkg.packageName + " attempting to redeclare permission "
10438 + perm.info.name + " already owned by " + bp.sourcePackage);
10439 res.origPermission = perm.info.name;
10440 res.origPackage = bp.sourcePackage;
10443 Slog.w(TAG, "Package " + pkg.packageName
10444 + " attempting to redeclare system permission "
10445 + perm.info.name + "; ignoring new declaration");
10446 pkg.permissions.remove(i);
10452 // Check if installing already existing package
10453 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10454 String oldName = mSettings.mRenamedPackages.get(pkgName);
10455 if (pkg.mOriginalPackages != null
10456 && pkg.mOriginalPackages.contains(oldName)
10457 && mPackages.containsKey(oldName)) {
10458 // This package is derived from an original package,
10459 // and this device has been updating from that original
10460 // name. We must continue using the original name, so
10461 // rename the new package here.
10462 pkg.setPackageName(oldName);
10463 pkgName = pkg.packageName;
10465 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
10466 + oldName + " pkgName=" + pkgName);
10467 } else if (mPackages.containsKey(pkgName)) {
10468 // This package, under its official name, already exists
10469 // on the device; we should replace it.
10471 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
10474 PackageSetting ps = mSettings.mPackages.get(pkgName);
10476 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
10477 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
10478 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
10479 systemApp = (ps.pkg.applicationInfo.flags &
10480 ApplicationInfo.FLAG_SYSTEM) != 0;
10482 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10486 if (systemApp && onSd) {
10487 // Disable updates to system apps on sdcard
10488 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10489 "Cannot install updates to system apps on sdcard");
10493 if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
10494 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
10499 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
10500 installerPackageName, res);
10502 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
10503 args.user, installerPackageName, res);
10505 synchronized (mPackages) {
10506 final PackageSetting ps = mSettings.mPackages.get(pkgName);
10508 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10513 private static boolean isForwardLocked(PackageParser.Package pkg) {
10514 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10517 private static boolean isForwardLocked(ApplicationInfo info) {
10518 return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10521 private boolean isForwardLocked(PackageSetting ps) {
10522 return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10525 private static boolean isMultiArch(PackageSetting ps) {
10526 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10529 private static boolean isMultiArch(ApplicationInfo info) {
10530 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10533 private static boolean isExternal(PackageParser.Package pkg) {
10534 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10537 private static boolean isExternal(PackageSetting ps) {
10538 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10541 private static boolean isExternal(ApplicationInfo info) {
10542 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10545 private static boolean isSystemApp(PackageParser.Package pkg) {
10546 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10549 private static boolean isPrivilegedApp(PackageParser.Package pkg) {
10550 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
10553 private static boolean isSystemApp(ApplicationInfo info) {
10554 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10557 private static boolean isSystemApp(PackageSetting ps) {
10558 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
10561 private static boolean isUpdatedSystemApp(PackageSetting ps) {
10562 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10565 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
10566 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10569 private static boolean isUpdatedSystemApp(ApplicationInfo info) {
10570 return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10573 private int packageFlagsToInstallFlags(PackageSetting ps) {
10574 int installFlags = 0;
10575 if (isExternal(ps)) {
10576 installFlags |= PackageManager.INSTALL_EXTERNAL;
10578 if (isForwardLocked(ps)) {
10579 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10581 return installFlags;
10584 private void deleteTempPackageFiles() {
10585 final FilenameFilter filter = new FilenameFilter() {
10586 public boolean accept(File dir, String name) {
10587 return name.startsWith("vmdl") && name.endsWith(".tmp");
10590 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
10596 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
10598 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
10603 public void deletePackage(final String packageName,
10604 final IPackageDeleteObserver2 observer, final int userId, final int flags) {
10605 mContext.enforceCallingOrSelfPermission(
10606 android.Manifest.permission.DELETE_PACKAGES, null);
10607 final int uid = Binder.getCallingUid();
10608 if (UserHandle.getUserId(uid) != userId) {
10609 mContext.enforceCallingPermission(
10610 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10611 "deletePackage for user " + userId);
10613 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
10615 observer.onPackageDeleted(packageName,
10616 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
10617 } catch (RemoteException re) {
10622 boolean uninstallBlocked = false;
10623 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
10624 int[] users = sUserManager.getUserIds();
10625 for (int i = 0; i < users.length; ++i) {
10626 if (getBlockUninstallForUser(packageName, users[i])) {
10627 uninstallBlocked = true;
10632 uninstallBlocked = getBlockUninstallForUser(packageName, userId);
10634 if (uninstallBlocked) {
10636 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
10638 } catch (RemoteException re) {
10643 if (DEBUG_REMOVE) {
10644 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
10646 // Queue up an async operation since the package deletion may take a little while.
10647 mHandler.post(new Runnable() {
10648 public void run() {
10649 mHandler.removeCallbacks(this);
10650 final int returnCode = deletePackageX(packageName, userId, flags);
10651 if (observer != null) {
10653 observer.onPackageDeleted(packageName, returnCode, null);
10654 } catch (RemoteException e) {
10655 Log.i(TAG, "Observer no longer exists.");
10662 private boolean isPackageDeviceAdmin(String packageName, int userId) {
10663 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
10664 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
10667 if (dpm.isDeviceOwner(packageName)) {
10671 if (userId == UserHandle.USER_ALL) {
10672 users = sUserManager.getUserIds();
10674 users = new int[]{userId};
10676 for (int i = 0; i < users.length; ++i) {
10677 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
10682 } catch (RemoteException e) {
10688 * This method is an internal method that could be get invoked either
10689 * to delete an installed package or to clean up a failed installation.
10690 * After deleting an installed package, a broadcast is sent to notify any
10691 * listeners that the package has been installed. For cleaning up a failed
10692 * installation, the broadcast is not necessary since the package's
10693 * installation wouldn't have sent the initial broadcast either
10694 * The key steps in deleting a package are
10695 * deleting the package information in internal structures like mPackages,
10696 * deleting the packages base directories through installd
10697 * updating mSettings to reflect current status
10698 * persisting settings for later use
10699 * sending a broadcast if necessary
10701 private int deletePackageX(String packageName, int userId, int flags) {
10702 final PackageRemovedInfo info = new PackageRemovedInfo();
10705 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
10706 ? UserHandle.ALL : new UserHandle(userId);
10708 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
10709 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
10710 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
10713 boolean removedForAllUsers = false;
10714 boolean systemUpdate = false;
10716 // for the uninstall-updates case and restricted profiles, remember the per-
10717 // userhandle installed state
10719 boolean[] perUserInstalled;
10720 synchronized (mPackages) {
10721 PackageSetting ps = mSettings.mPackages.get(packageName);
10722 allUsers = sUserManager.getUserIds();
10723 perUserInstalled = new boolean[allUsers.length];
10724 for (int i = 0; i < allUsers.length; i++) {
10725 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10729 synchronized (mInstallLock) {
10730 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
10731 res = deletePackageLI(packageName, removeForUser,
10732 true, allUsers, perUserInstalled,
10733 flags | REMOVE_CHATTY, info, true);
10734 systemUpdate = info.isRemovedPackageSystemUpdate;
10735 if (res && !systemUpdate && mPackages.get(packageName) == null) {
10736 removedForAllUsers = true;
10738 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
10739 + " removedForAllUsers=" + removedForAllUsers);
10743 info.sendBroadcast(true, systemUpdate, removedForAllUsers);
10745 // If the removed package was a system update, the old system package
10746 // was re-enabled; we need to broadcast this information
10747 if (systemUpdate) {
10748 Bundle extras = new Bundle(1);
10749 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
10750 ? info.removedAppId : info.uid);
10751 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10753 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
10754 extras, null, null, null);
10755 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
10756 extras, null, null, null);
10757 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
10758 null, packageName, null, null);
10761 // Force a gc here.
10762 Runtime.getRuntime().gc();
10763 // Delete the resources here after sending the broadcast to let
10764 // other processes clean up before deleting resources.
10765 if (info.args != null) {
10766 synchronized (mInstallLock) {
10767 info.args.doPostDeleteLI(true);
10771 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
10774 static class PackageRemovedInfo {
10775 String removedPackage;
10777 int removedAppId = -1;
10778 int[] removedUsers = null;
10779 boolean isRemovedPackageSystemUpdate = false;
10780 // Clean up resources deleted packages.
10781 InstallArgs args = null;
10783 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
10784 Bundle extras = new Bundle(1);
10785 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
10786 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
10788 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10790 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
10791 if (removedPackage != null) {
10792 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
10793 extras, null, null, removedUsers);
10794 if (fullRemove && !replacing) {
10795 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
10796 extras, null, null, removedUsers);
10799 if (removedAppId >= 0) {
10800 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
10807 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
10808 * flag is not set, the data directory is removed as well.
10809 * make sure this flag is set for partially installed apps. If not its meaningless to
10810 * delete a partially installed application.
10812 private void removePackageDataLI(PackageSetting ps,
10813 int[] allUserHandles, boolean[] perUserInstalled,
10814 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
10815 String packageName = ps.name;
10816 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
10817 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
10818 // Retrieve object to delete permissions for shared user later on
10819 final PackageSetting deletedPs;
10821 synchronized (mPackages) {
10822 deletedPs = mSettings.mPackages.get(packageName);
10823 if (outInfo != null) {
10824 outInfo.removedPackage = packageName;
10825 outInfo.removedUsers = deletedPs != null
10826 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
10830 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10831 removeDataDirsLI(packageName);
10832 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
10835 synchronized (mPackages) {
10836 if (deletedPs != null) {
10837 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10838 if (outInfo != null) {
10839 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
10840 outInfo.removedAppId = mSettings.removePackageLPw(packageName);
10842 if (deletedPs != null) {
10843 updatePermissionsLPw(deletedPs.name, null, 0);
10844 if (deletedPs.sharedUser != null) {
10845 // remove permissions associated with package
10846 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
10849 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
10851 // make sure to preserve per-user disabled state if this removal was just
10852 // a downgrade of a system app to the factory package
10853 if (allUserHandles != null && perUserInstalled != null) {
10854 if (DEBUG_REMOVE) {
10855 Slog.d(TAG, "Propagating install state across downgrade");
10857 for (int i = 0; i < allUserHandles.length; i++) {
10858 if (DEBUG_REMOVE) {
10859 Slog.d(TAG, " user " + allUserHandles[i]
10860 + " => " + perUserInstalled[i]);
10862 ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10866 // can downgrade to reader
10867 if (writeSettings) {
10868 // Save settings now
10869 mSettings.writeLPr();
10872 if (outInfo != null) {
10873 // A user ID was deleted here. Go through all users and remove it
10875 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
10879 static boolean locationIsPrivileged(File path) {
10881 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
10882 .getCanonicalPath();
10883 return path.getCanonicalPath().startsWith(privilegedAppDir);
10884 } catch (IOException e) {
10885 Slog.e(TAG, "Unable to access code path " + path);
10891 * Tries to delete system package.
10893 private boolean deleteSystemPackageLI(PackageSetting newPs,
10894 int[] allUserHandles, boolean[] perUserInstalled,
10895 int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
10896 final boolean applyUserRestrictions
10897 = (allUserHandles != null) && (perUserInstalled != null);
10898 PackageSetting disabledPs = null;
10899 // Confirm if the system package has been updated
10900 // An updated system app can be deleted. This will also have to restore
10901 // the system pkg from system partition
10903 synchronized (mPackages) {
10904 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
10906 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
10907 + " disabledPs=" + disabledPs);
10908 if (disabledPs == null) {
10909 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
10911 } else if (DEBUG_REMOVE) {
10912 Slog.d(TAG, "Deleting system pkg from data partition");
10914 if (DEBUG_REMOVE) {
10915 if (applyUserRestrictions) {
10916 Slog.d(TAG, "Remembering install states:");
10917 for (int i = 0; i < allUserHandles.length; i++) {
10918 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
10922 // Delete the updated package
10923 outInfo.isRemovedPackageSystemUpdate = true;
10924 if (disabledPs.versionCode < newPs.versionCode) {
10925 // Delete data for downgrades
10926 flags &= ~PackageManager.DELETE_KEEP_DATA;
10928 // Preserve data by setting flag
10929 flags |= PackageManager.DELETE_KEEP_DATA;
10931 boolean ret = deleteInstalledPackageLI(newPs, true, flags,
10932 allUserHandles, perUserInstalled, outInfo, writeSettings);
10937 synchronized (mPackages) {
10938 // Reinstate the old system package
10939 mSettings.enableSystemPackageLPw(newPs.name);
10940 // Remove any native libraries from the upgraded package.
10941 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
10943 // Install the system package
10944 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
10945 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
10946 if (locationIsPrivileged(disabledPs.codePath)) {
10947 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10950 final PackageParser.Package newPkg;
10952 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
10953 } catch (PackageManagerException e) {
10954 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
10959 synchronized (mPackages) {
10960 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
10961 updatePermissionsLPw(newPkg.packageName, newPkg,
10962 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
10963 if (applyUserRestrictions) {
10964 if (DEBUG_REMOVE) {
10965 Slog.d(TAG, "Propagating install state across reinstall");
10967 for (int i = 0; i < allUserHandles.length; i++) {
10968 if (DEBUG_REMOVE) {
10969 Slog.d(TAG, " user " + allUserHandles[i]
10970 + " => " + perUserInstalled[i]);
10972 ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10974 // Regardless of writeSettings we need to ensure that this restriction
10975 // state propagation is persisted
10976 mSettings.writeAllUsersPackageRestrictionsLPr();
10978 // can downgrade to reader here
10979 if (writeSettings) {
10980 mSettings.writeLPr();
10986 private boolean deleteInstalledPackageLI(PackageSetting ps,
10987 boolean deleteCodeAndResources, int flags,
10988 int[] allUserHandles, boolean[] perUserInstalled,
10989 PackageRemovedInfo outInfo, boolean writeSettings) {
10990 if (outInfo != null) {
10991 outInfo.uid = ps.appId;
10994 // Delete package data from internal structures and also remove data if flag is set
10995 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
10997 // Delete application code and resources
10998 if (deleteCodeAndResources && (outInfo != null)) {
10999 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
11000 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
11001 getAppDexInstructionSets(ps));
11002 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
11008 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
11010 mContext.enforceCallingOrSelfPermission(
11011 android.Manifest.permission.DELETE_PACKAGES, null);
11012 synchronized (mPackages) {
11013 PackageSetting ps = mSettings.mPackages.get(packageName);
11015 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
11018 if (!ps.getInstalled(userId)) {
11019 // Can't block uninstall for an app that is not installed or enabled.
11020 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
11023 ps.setBlockUninstall(blockUninstall, userId);
11024 mSettings.writePackageRestrictionsLPr(userId);
11030 public boolean getBlockUninstallForUser(String packageName, int userId) {
11031 synchronized (mPackages) {
11032 PackageSetting ps = mSettings.mPackages.get(packageName);
11034 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
11037 return ps.getBlockUninstall(userId);
11042 * This method handles package deletion in general
11044 private boolean deletePackageLI(String packageName, UserHandle user,
11045 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
11046 int flags, PackageRemovedInfo outInfo,
11047 boolean writeSettings) {
11048 if (packageName == null) {
11049 Slog.w(TAG, "Attempt to delete null packageName.");
11052 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
11054 boolean dataOnly = false;
11055 int removeUser = -1;
11057 synchronized (mPackages) {
11058 ps = mSettings.mPackages.get(packageName);
11060 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11063 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
11064 && user.getIdentifier() != UserHandle.USER_ALL) {
11065 // The caller is asking that the package only be deleted for a single
11066 // user. To do this, we just mark its uninstalled state and delete
11067 // its data. If this is a system app, we only allow this to happen if
11068 // they have set the special DELETE_SYSTEM_APP which requests different
11069 // semantics than normal for uninstalling system apps.
11070 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
11071 ps.setUserState(user.getIdentifier(),
11072 COMPONENT_ENABLED_STATE_DEFAULT,
11075 true, //notLaunched
11078 false // blockUninstall
11080 if (!isSystemApp(ps)) {
11081 if (ps.isAnyInstalled(sUserManager.getUserIds())) {
11082 // Other user still have this package installed, so all
11083 // we need to do is clear this user's data and save that
11084 // it is uninstalled.
11085 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
11086 removeUser = user.getIdentifier();
11088 mSettings.writePackageRestrictionsLPr(removeUser);
11090 // We need to set it back to 'installed' so the uninstall
11091 // broadcasts will be sent correctly.
11092 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
11093 ps.setInstalled(true, user.getIdentifier());
11096 // This is a system app, so we assume that the
11097 // other users still have this package installed, so all
11098 // we need to do is clear this user's data and save that
11099 // it is uninstalled.
11100 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
11101 removeUser = user.getIdentifier();
11103 mSettings.writePackageRestrictionsLPr(removeUser);
11108 if (removeUser >= 0) {
11109 // From above, we determined that we are deleting this only
11110 // for a single user. Continue the work here.
11111 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
11112 if (outInfo != null) {
11113 outInfo.removedPackage = packageName;
11114 outInfo.removedAppId = appId;
11115 outInfo.removedUsers = new int[] {removeUser};
11117 mInstaller.clearUserData(packageName, removeUser);
11118 removeKeystoreDataIfNeeded(removeUser, appId);
11119 schedulePackageCleaning(packageName, removeUser, false);
11124 // Delete application data first
11125 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
11126 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
11130 boolean ret = false;
11131 if (isSystemApp(ps)) {
11132 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
11133 // When an updated system application is deleted we delete the existing resources as well and
11134 // fall back to existing code in system partition
11135 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
11136 flags, outInfo, writeSettings);
11138 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
11139 // Kill application pre-emptively especially for apps on sd.
11140 killApplication(packageName, ps.appId, "uninstall pkg");
11141 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
11142 allUserHandles, perUserInstalled,
11143 outInfo, writeSettings);
11149 private final class ClearStorageConnection implements ServiceConnection {
11150 IMediaContainerService mContainerService;
11153 public void onServiceConnected(ComponentName name, IBinder service) {
11154 synchronized (this) {
11155 mContainerService = IMediaContainerService.Stub.asInterface(service);
11161 public void onServiceDisconnected(ComponentName name) {
11165 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
11166 final boolean mounted;
11167 if (Environment.isExternalStorageEmulated()) {
11170 final String status = Environment.getExternalStorageState();
11172 mounted = status.equals(Environment.MEDIA_MOUNTED)
11173 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
11180 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
11182 if (userId == UserHandle.USER_ALL) {
11183 users = sUserManager.getUserIds();
11185 users = new int[] { userId };
11187 final ClearStorageConnection conn = new ClearStorageConnection();
11188 if (mContext.bindServiceAsUser(
11189 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
11191 for (int curUser : users) {
11192 long timeout = SystemClock.uptimeMillis() + 5000;
11193 synchronized (conn) {
11194 long now = SystemClock.uptimeMillis();
11195 while (conn.mContainerService == null && now < timeout) {
11197 conn.wait(timeout - now);
11198 } catch (InterruptedException e) {
11202 if (conn.mContainerService == null) {
11206 final UserEnvironment userEnv = new UserEnvironment(curUser);
11207 clearDirectory(conn.mContainerService,
11208 userEnv.buildExternalStorageAppCacheDirs(packageName));
11210 clearDirectory(conn.mContainerService,
11211 userEnv.buildExternalStorageAppDataDirs(packageName));
11212 clearDirectory(conn.mContainerService,
11213 userEnv.buildExternalStorageAppMediaDirs(packageName));
11217 mContext.unbindService(conn);
11223 public void clearApplicationUserData(final String packageName,
11224 final IPackageDataObserver observer, final int userId) {
11225 mContext.enforceCallingOrSelfPermission(
11226 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
11227 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
11228 // Queue up an async operation since the package deletion may take a little while.
11229 mHandler.post(new Runnable() {
11230 public void run() {
11231 mHandler.removeCallbacks(this);
11232 final boolean succeeded;
11233 synchronized (mInstallLock) {
11234 succeeded = clearApplicationUserDataLI(packageName, userId);
11236 clearExternalStorageDataSync(packageName, userId, true);
11238 // invoke DeviceStorageMonitor's update method to clear any notifications
11239 DeviceStorageMonitorInternal
11240 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
11245 if(observer != null) {
11247 observer.onRemoveCompleted(packageName, succeeded);
11248 } catch (RemoteException e) {
11249 Log.i(TAG, "Observer no longer exists.");
11251 } //end if observer
11256 private boolean clearApplicationUserDataLI(String packageName, int userId) {
11257 if (packageName == null) {
11258 Slog.w(TAG, "Attempt to delete null packageName.");
11262 // Try finding details about the requested package
11263 PackageParser.Package pkg;
11264 synchronized (mPackages) {
11265 pkg = mPackages.get(packageName);
11267 final PackageSetting ps = mSettings.mPackages.get(packageName);
11275 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11278 // Always delete data directories for package, even if we found no other
11279 // record of app. This helps users recover from UID mismatches without
11280 // resorting to a full data wipe.
11281 int retCode = mInstaller.clearUserData(packageName, userId);
11283 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
11291 if (pkg != null && pkg.applicationInfo != null) {
11292 final int appId = pkg.applicationInfo.uid;
11293 removeKeystoreDataIfNeeded(userId, appId);
11296 // Create a native library symlink only if we have native libraries
11297 // and if the native libraries are 32 bit libraries. We do not provide
11298 // this symlink for 64 bit libraries.
11299 if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
11300 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
11301 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
11302 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
11303 Slog.w(TAG, "Failed linking native library dir");
11312 * Remove entries from the keystore daemon. Will only remove it if the
11313 * {@code appId} is valid.
11315 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
11320 final KeyStore keyStore = KeyStore.getInstance();
11321 if (keyStore != null) {
11322 if (userId == UserHandle.USER_ALL) {
11323 for (final int individual : sUserManager.getUserIds()) {
11324 keyStore.clearUid(UserHandle.getUid(individual, appId));
11327 keyStore.clearUid(UserHandle.getUid(userId, appId));
11330 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
11335 public void deleteApplicationCacheFiles(final String packageName,
11336 final IPackageDataObserver observer) {
11337 mContext.enforceCallingOrSelfPermission(
11338 android.Manifest.permission.DELETE_CACHE_FILES, null);
11339 // Queue up an async operation since the package deletion may take a little while.
11340 final int userId = UserHandle.getCallingUserId();
11341 mHandler.post(new Runnable() {
11342 public void run() {
11343 mHandler.removeCallbacks(this);
11344 final boolean succeded;
11345 synchronized (mInstallLock) {
11346 succeded = deleteApplicationCacheFilesLI(packageName, userId);
11348 clearExternalStorageDataSync(packageName, userId, false);
11349 if(observer != null) {
11351 observer.onRemoveCompleted(packageName, succeded);
11352 } catch (RemoteException e) {
11353 Log.i(TAG, "Observer no longer exists.");
11355 } //end if observer
11360 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
11361 if (packageName == null) {
11362 Slog.w(TAG, "Attempt to delete null packageName.");
11365 PackageParser.Package p;
11366 synchronized (mPackages) {
11367 p = mPackages.get(packageName);
11370 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11373 final ApplicationInfo applicationInfo = p.applicationInfo;
11374 if (applicationInfo == null) {
11375 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11378 int retCode = mInstaller.deleteCacheFiles(packageName, userId);
11380 Slog.w(TAG, "Couldn't remove cache files for package: "
11381 + packageName + " u" + userId);
11388 public void getPackageSizeInfo(final String packageName, int userHandle,
11389 final IPackageStatsObserver observer) {
11390 mContext.enforceCallingOrSelfPermission(
11391 android.Manifest.permission.GET_PACKAGE_SIZE, null);
11392 if (packageName == null) {
11393 throw new IllegalArgumentException("Attempt to get size of null packageName");
11396 PackageStats stats = new PackageStats(packageName, userHandle);
11399 * Queue up an async operation since the package measurement may take a
11402 Message msg = mHandler.obtainMessage(INIT_COPY);
11403 msg.obj = new MeasureParams(stats, observer);
11404 mHandler.sendMessage(msg);
11407 private boolean getPackageSizeInfoLI(String packageName, int userHandle,
11408 PackageStats pStats) {
11409 if (packageName == null) {
11410 Slog.w(TAG, "Attempt to get size of null packageName.");
11413 PackageParser.Package p;
11414 boolean dataOnly = false;
11415 String libDirRoot = null;
11416 String asecPath = null;
11417 PackageSetting ps = null;
11418 synchronized (mPackages) {
11419 p = mPackages.get(packageName);
11420 ps = mSettings.mPackages.get(packageName);
11423 if((ps == null) || (ps.pkg == null)) {
11424 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11430 libDirRoot = ps.legacyNativeLibraryPathString;
11432 if (p != null && (isExternal(p) || isForwardLocked(p))) {
11433 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
11434 if (secureContainerId != null) {
11435 asecPath = PackageHelper.getSdFilesystem(secureContainerId);
11439 String publicSrcDir = null;
11441 final ApplicationInfo applicationInfo = p.applicationInfo;
11442 if (applicationInfo == null) {
11443 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11446 if (isForwardLocked(p)) {
11447 publicSrcDir = applicationInfo.getBaseResourcePath();
11450 // TODO: extend to measure size of split APKs
11451 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
11452 // not just the first level.
11453 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
11454 // just the primary.
11455 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
11456 int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
11457 publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
11462 // Fix-up for forward-locked applications in ASEC containers.
11463 if (!isExternal(p)) {
11464 pStats.codeSize += pStats.externalCodeSize;
11465 pStats.externalCodeSize = 0L;
11473 public void addPackageToPreferred(String packageName) {
11474 Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
11478 public void removePackageFromPreferred(String packageName) {
11479 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
11483 public List<PackageInfo> getPreferredPackages(int flags) {
11484 return new ArrayList<PackageInfo>();
11487 private int getUidTargetSdkVersionLockedLPr(int uid) {
11488 Object obj = mSettings.getUserIdLPr(uid);
11489 if (obj instanceof SharedUserSetting) {
11490 final SharedUserSetting sus = (SharedUserSetting) obj;
11491 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
11492 final Iterator<PackageSetting> it = sus.packages.iterator();
11493 while (it.hasNext()) {
11494 final PackageSetting ps = it.next();
11495 if (ps.pkg != null) {
11496 int v = ps.pkg.applicationInfo.targetSdkVersion;
11497 if (v < vers) vers = v;
11501 } else if (obj instanceof PackageSetting) {
11502 final PackageSetting ps = (PackageSetting) obj;
11503 if (ps.pkg != null) {
11504 return ps.pkg.applicationInfo.targetSdkVersion;
11507 return Build.VERSION_CODES.CUR_DEVELOPMENT;
11511 public void addPreferredActivity(IntentFilter filter, int match,
11512 ComponentName[] set, ComponentName activity, int userId) {
11513 addPreferredActivityInternal(filter, match, set, activity, true, userId,
11514 "Adding preferred");
11517 private void addPreferredActivityInternal(IntentFilter filter, int match,
11518 ComponentName[] set, ComponentName activity, boolean always, int userId,
11521 int callingUid = Binder.getCallingUid();
11522 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
11523 if (filter.countActions() == 0) {
11524 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11527 synchronized (mPackages) {
11528 if (mContext.checkCallingOrSelfPermission(
11529 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11530 != PackageManager.PERMISSION_GRANTED) {
11531 if (getUidTargetSdkVersionLockedLPr(callingUid)
11532 < Build.VERSION_CODES.FROYO) {
11533 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
11537 mContext.enforceCallingOrSelfPermission(
11538 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11541 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
11542 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
11544 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11545 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
11546 mSettings.writePackageRestrictionsLPr(userId);
11551 public void replacePreferredActivity(IntentFilter filter, int match,
11552 ComponentName[] set, ComponentName activity, int userId) {
11553 if (filter.countActions() != 1) {
11554 throw new IllegalArgumentException(
11555 "replacePreferredActivity expects filter to have only 1 action.");
11557 if (filter.countDataAuthorities() != 0
11558 || filter.countDataPaths() != 0
11559 || filter.countDataSchemes() > 1
11560 || filter.countDataTypes() != 0) {
11561 throw new IllegalArgumentException(
11562 "replacePreferredActivity expects filter to have no data authorities, " +
11563 "paths, or types; and at most one scheme.");
11566 final int callingUid = Binder.getCallingUid();
11567 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
11568 synchronized (mPackages) {
11569 if (mContext.checkCallingOrSelfPermission(
11570 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11571 != PackageManager.PERMISSION_GRANTED) {
11572 if (getUidTargetSdkVersionLockedLPr(callingUid)
11573 < Build.VERSION_CODES.FROYO) {
11574 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
11575 + Binder.getCallingUid());
11578 mContext.enforceCallingOrSelfPermission(
11579 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11582 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11584 // Get all of the existing entries that exactly match this filter.
11585 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
11586 if (existing != null && existing.size() == 1) {
11587 PreferredActivity cur = existing.get(0);
11588 if (DEBUG_PREFERRED) {
11589 Slog.i(TAG, "Checking replace of preferred:");
11590 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11591 if (!cur.mPref.mAlways) {
11592 Slog.i(TAG, " -- CUR; not mAlways!");
11594 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
11595 Slog.i(TAG, " -- CUR: mSet="
11596 + Arrays.toString(cur.mPref.mSetComponents));
11597 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
11598 Slog.i(TAG, " -- NEW: mMatch="
11599 + (match&IntentFilter.MATCH_CATEGORY_MASK));
11600 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
11601 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
11604 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
11605 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
11606 && cur.mPref.sameSet(set)) {
11607 // Setting the preferred activity to what it happens to be already
11608 if (DEBUG_PREFERRED) {
11609 Slog.i(TAG, "Replacing with same preferred activity "
11610 + cur.mPref.mShortComponent + " for user "
11612 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11618 if (existing != null) {
11619 if (DEBUG_PREFERRED) {
11620 Slog.i(TAG, existing.size() + " existing preferred matches for:");
11621 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11623 for (int i = 0; i < existing.size(); i++) {
11624 PreferredActivity pa = existing.get(i);
11625 if (DEBUG_PREFERRED) {
11626 Slog.i(TAG, "Removing existing preferred activity "
11627 + pa.mPref.mComponent + ":");
11628 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
11630 pir.removeFilter(pa);
11634 addPreferredActivityInternal(filter, match, set, activity, true, userId,
11635 "Replacing preferred");
11640 public void clearPackagePreferredActivities(String packageName) {
11641 final int uid = Binder.getCallingUid();
11643 synchronized (mPackages) {
11644 PackageParser.Package pkg = mPackages.get(packageName);
11645 if (pkg == null || pkg.applicationInfo.uid != uid) {
11646 if (mContext.checkCallingOrSelfPermission(
11647 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11648 != PackageManager.PERMISSION_GRANTED) {
11649 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
11650 < Build.VERSION_CODES.FROYO) {
11651 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
11652 + Binder.getCallingUid());
11655 mContext.enforceCallingOrSelfPermission(
11656 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11660 int user = UserHandle.getCallingUserId();
11661 if (clearPackagePreferredActivitiesLPw(packageName, user)) {
11662 mSettings.writePackageRestrictionsLPr(user);
11663 scheduleWriteSettingsLocked();
11668 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
11669 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
11670 ArrayList<PreferredActivity> removed = null;
11671 boolean changed = false;
11672 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
11673 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
11674 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
11675 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
11678 Iterator<PreferredActivity> it = pir.filterIterator();
11679 while (it.hasNext()) {
11680 PreferredActivity pa = it.next();
11681 // Mark entry for removal only if it matches the package name
11682 // and the entry is of type "always".
11683 if (packageName == null ||
11684 (pa.mPref.mComponent.getPackageName().equals(packageName)
11685 && pa.mPref.mAlways)) {
11686 if (removed == null) {
11687 removed = new ArrayList<PreferredActivity>();
11692 if (removed != null) {
11693 for (int j=0; j<removed.size(); j++) {
11694 PreferredActivity pa = removed.get(j);
11695 pir.removeFilter(pa);
11704 public void resetPreferredActivities(int userId) {
11705 /* TODO: Actually use userId. Why is it being passed in? */
11706 mContext.enforceCallingOrSelfPermission(
11707 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11709 synchronized (mPackages) {
11710 int user = UserHandle.getCallingUserId();
11711 clearPackagePreferredActivitiesLPw(null, user);
11712 mSettings.readDefaultPreferredAppsLPw(this, user);
11713 mSettings.writePackageRestrictionsLPr(user);
11714 scheduleWriteSettingsLocked();
11719 public int getPreferredActivities(List<IntentFilter> outFilters,
11720 List<ComponentName> outActivities, String packageName) {
11723 final int userId = UserHandle.getCallingUserId();
11725 synchronized (mPackages) {
11726 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11728 final Iterator<PreferredActivity> it = pir.filterIterator();
11729 while (it.hasNext()) {
11730 final PreferredActivity pa = it.next();
11731 if (packageName == null
11732 || (pa.mPref.mComponent.getPackageName().equals(packageName)
11733 && pa.mPref.mAlways)) {
11734 if (outFilters != null) {
11735 outFilters.add(new IntentFilter(pa));
11737 if (outActivities != null) {
11738 outActivities.add(pa.mPref.mComponent);
11749 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
11751 int callingUid = Binder.getCallingUid();
11752 if (callingUid != Process.SYSTEM_UID) {
11753 throw new SecurityException(
11754 "addPersistentPreferredActivity can only be run by the system");
11756 if (filter.countActions() == 0) {
11757 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11760 synchronized (mPackages) {
11761 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
11763 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11764 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
11765 new PersistentPreferredActivity(filter, activity));
11766 mSettings.writePackageRestrictionsLPr(userId);
11771 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
11772 int callingUid = Binder.getCallingUid();
11773 if (callingUid != Process.SYSTEM_UID) {
11774 throw new SecurityException(
11775 "clearPackagePersistentPreferredActivities can only be run by the system");
11777 ArrayList<PersistentPreferredActivity> removed = null;
11778 boolean changed = false;
11779 synchronized (mPackages) {
11780 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
11781 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
11782 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
11784 if (userId != thisUserId) {
11787 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
11788 while (it.hasNext()) {
11789 PersistentPreferredActivity ppa = it.next();
11790 // Mark entry for removal only if it matches the package name.
11791 if (ppa.mComponent.getPackageName().equals(packageName)) {
11792 if (removed == null) {
11793 removed = new ArrayList<PersistentPreferredActivity>();
11798 if (removed != null) {
11799 for (int j=0; j<removed.size(); j++) {
11800 PersistentPreferredActivity ppa = removed.get(j);
11801 ppir.removeFilter(ppa);
11808 mSettings.writePackageRestrictionsLPr(userId);
11814 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
11815 int ownerUserId, int sourceUserId, int targetUserId, int flags) {
11816 mContext.enforceCallingOrSelfPermission(
11817 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11818 int callingUid = Binder.getCallingUid();
11819 enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11820 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11821 if (intentFilter.countActions() == 0) {
11822 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
11825 synchronized (mPackages) {
11826 CrossProfileIntentFilter filter = new CrossProfileIntentFilter(intentFilter,
11827 ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
11828 mSettings.editCrossProfileIntentResolverLPw(sourceUserId).addFilter(filter);
11829 mSettings.writePackageRestrictionsLPr(sourceUserId);
11834 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
11836 mContext.enforceCallingOrSelfPermission(
11837 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11838 int callingUid = Binder.getCallingUid();
11839 enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11840 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11841 int callingUserId = UserHandle.getUserId(callingUid);
11842 synchronized (mPackages) {
11843 CrossProfileIntentResolver resolver =
11844 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
11845 HashSet<CrossProfileIntentFilter> set =
11846 new HashSet<CrossProfileIntentFilter>(resolver.filterSet());
11847 for (CrossProfileIntentFilter filter : set) {
11848 if (filter.getOwnerPackage().equals(ownerPackage)
11849 && filter.getOwnerUserId() == callingUserId) {
11850 resolver.removeFilter(filter);
11853 mSettings.writePackageRestrictionsLPr(sourceUserId);
11857 // Enforcing that callingUid is owning pkg on userId
11858 private void enforceOwnerRights(String pkg, int userId, int callingUid) {
11859 // The system owns everything.
11860 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
11863 int callingUserId = UserHandle.getUserId(callingUid);
11864 if (callingUserId != userId) {
11865 throw new SecurityException("calling uid " + callingUid
11866 + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
11869 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
11871 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
11874 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
11875 throw new SecurityException("Calling uid " + callingUid
11876 + " does not own package " + pkg);
11881 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
11882 Intent intent = new Intent(Intent.ACTION_MAIN);
11883 intent.addCategory(Intent.CATEGORY_HOME);
11885 final int callingUserId = UserHandle.getCallingUserId();
11886 List<ResolveInfo> list = queryIntentActivities(intent, null,
11887 PackageManager.GET_META_DATA, callingUserId);
11888 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
11889 true, false, false, callingUserId);
11891 allHomeCandidates.clear();
11892 if (list != null) {
11893 for (ResolveInfo ri : list) {
11894 allHomeCandidates.add(ri);
11897 return (preferred == null || preferred.activityInfo == null)
11899 : new ComponentName(preferred.activityInfo.packageName,
11900 preferred.activityInfo.name);
11904 public void setApplicationEnabledSetting(String appPackageName,
11905 int newState, int flags, int userId, String callingPackage) {
11906 if (!sUserManager.exists(userId)) return;
11907 if (callingPackage == null) {
11908 callingPackage = Integer.toString(Binder.getCallingUid());
11910 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
11914 public void setComponentEnabledSetting(ComponentName componentName,
11915 int newState, int flags, int userId) {
11916 if (!sUserManager.exists(userId)) return;
11917 setEnabledSetting(componentName.getPackageName(),
11918 componentName.getClassName(), newState, flags, userId, null);
11921 private void setEnabledSetting(final String packageName, String className, int newState,
11922 final int flags, int userId, String callingPackage) {
11923 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
11924 || newState == COMPONENT_ENABLED_STATE_ENABLED
11925 || newState == COMPONENT_ENABLED_STATE_DISABLED
11926 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
11927 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
11928 throw new IllegalArgumentException("Invalid new component state: "
11931 PackageSetting pkgSetting;
11932 final int uid = Binder.getCallingUid();
11933 final int permission = mContext.checkCallingOrSelfPermission(
11934 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
11935 enforceCrossUserPermission(uid, userId, false, true, "set enabled");
11936 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
11937 boolean sendNow = false;
11938 boolean isApp = (className == null);
11939 String componentName = isApp ? packageName : className;
11940 int packageUid = -1;
11941 ArrayList<String> components;
11944 synchronized (mPackages) {
11945 pkgSetting = mSettings.mPackages.get(packageName);
11946 if (pkgSetting == null) {
11947 if (className == null) {
11948 throw new IllegalArgumentException(
11949 "Unknown package: " + packageName);
11951 throw new IllegalArgumentException(
11952 "Unknown component: " + packageName
11953 + "/" + className);
11955 // Allow root and verify that userId is not being specified by a different user
11956 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
11957 throw new SecurityException(
11958 "Permission Denial: attempt to change component state from pid="
11959 + Binder.getCallingPid()
11960 + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
11962 if (className == null) {
11963 // We're dealing with an application/package level state change
11964 if (pkgSetting.getEnabled(userId) == newState) {
11968 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
11969 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
11970 // Don't care about who enables an app.
11971 callingPackage = null;
11973 pkgSetting.setEnabled(newState, userId, callingPackage);
11974 // pkgSetting.pkg.mSetEnabled = newState;
11976 // We're dealing with a component level state change
11977 // First, verify that this is a valid class name.
11978 PackageParser.Package pkg = pkgSetting.pkg;
11979 if (pkg == null || !pkg.hasComponentClassName(className)) {
11980 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
11981 throw new IllegalArgumentException("Component class " + className
11982 + " does not exist in " + packageName);
11984 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
11985 + className + " does not exist in " + packageName);
11988 switch (newState) {
11989 case COMPONENT_ENABLED_STATE_ENABLED:
11990 if (!pkgSetting.enableComponentLPw(className, userId)) {
11994 case COMPONENT_ENABLED_STATE_DISABLED:
11995 if (!pkgSetting.disableComponentLPw(className, userId)) {
11999 case COMPONENT_ENABLED_STATE_DEFAULT:
12000 if (!pkgSetting.restoreComponentLPw(className, userId)) {
12005 Slog.e(TAG, "Invalid new component state: " + newState);
12009 mSettings.writePackageRestrictionsLPr(userId);
12010 components = mPendingBroadcasts.get(userId, packageName);
12011 final boolean newPackage = components == null;
12013 components = new ArrayList<String>();
12015 if (!components.contains(componentName)) {
12016 components.add(componentName);
12018 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
12020 // Purge entry from pending broadcast list if another one exists already
12021 // since we are sending one right away.
12022 mPendingBroadcasts.remove(userId, packageName);
12025 mPendingBroadcasts.put(userId, packageName, components);
12027 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
12028 // Schedule a message
12029 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
12034 long callingId = Binder.clearCallingIdentity();
12037 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
12038 sendPackageChangedBroadcast(packageName,
12039 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
12042 Binder.restoreCallingIdentity(callingId);
12046 private void sendPackageChangedBroadcast(String packageName,
12047 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
12049 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
12051 Bundle extras = new Bundle(4);
12052 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
12053 String nameList[] = new String[componentNames.size()];
12054 componentNames.toArray(nameList);
12055 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
12056 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
12057 extras.putInt(Intent.EXTRA_UID, packageUid);
12058 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
12059 new int[] {UserHandle.getUserId(packageUid)});
12063 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
12064 if (!sUserManager.exists(userId)) return;
12065 final int uid = Binder.getCallingUid();
12066 final int permission = mContext.checkCallingOrSelfPermission(
12067 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
12068 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
12069 enforceCrossUserPermission(uid, userId, true, true, "stop package");
12071 synchronized (mPackages) {
12072 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
12074 scheduleWritePackageRestrictionsLocked(userId);
12080 public String getInstallerPackageName(String packageName) {
12082 synchronized (mPackages) {
12083 return mSettings.getInstallerPackageNameLPr(packageName);
12088 public int getApplicationEnabledSetting(String packageName, int userId) {
12089 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12090 int uid = Binder.getCallingUid();
12091 enforceCrossUserPermission(uid, userId, false, false, "get enabled");
12093 synchronized (mPackages) {
12094 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
12099 public int getComponentEnabledSetting(ComponentName componentName, int userId) {
12100 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12101 int uid = Binder.getCallingUid();
12102 enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
12104 synchronized (mPackages) {
12105 return mSettings.getComponentEnabledSettingLPr(componentName, userId);
12110 public void enterSafeMode() {
12111 enforceSystemOrRoot("Only the system can request entering safe mode");
12113 if (!mSystemReady) {
12119 public void systemReady() {
12120 mSystemReady = true;
12122 // Read the compatibilty setting when the system is ready.
12123 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
12124 mContext.getContentResolver(),
12125 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
12126 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
12127 if (DEBUG_SETTINGS) {
12128 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
12131 synchronized (mPackages) {
12132 // Verify that all of the preferred activity components actually
12133 // exist. It is possible for applications to be updated and at
12134 // that point remove a previously declared activity component that
12135 // had been set as a preferred activity. We try to clean this up
12136 // the next time we encounter that preferred activity, but it is
12137 // possible for the user flow to never be able to return to that
12138 // situation so here we do a sanity check to make sure we haven't
12139 // left any junk around.
12140 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
12141 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12142 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12144 for (PreferredActivity pa : pir.filterSet()) {
12145 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
12149 if (removed.size() > 0) {
12150 for (int r=0; r<removed.size(); r++) {
12151 PreferredActivity pa = removed.get(r);
12152 Slog.w(TAG, "Removing dangling preferred activity: "
12153 + pa.mPref.mComponent);
12154 pir.removeFilter(pa);
12156 mSettings.writePackageRestrictionsLPr(
12157 mSettings.mPreferredActivities.keyAt(i));
12161 sUserManager.systemReady();
12163 // Kick off any messages waiting for system ready
12164 if (mPostSystemReadyMessages != null) {
12165 for (Message msg : mPostSystemReadyMessages) {
12166 msg.sendToTarget();
12168 mPostSystemReadyMessages = null;
12173 public boolean isSafeMode() {
12178 public boolean hasSystemUidErrors() {
12179 return mHasSystemUidErrors;
12182 static String arrayToString(int[] array) {
12183 StringBuffer buf = new StringBuffer(128);
12185 if (array != null) {
12186 for (int i=0; i<array.length; i++) {
12187 if (i > 0) buf.append(", ");
12188 buf.append(array[i]);
12192 return buf.toString();
12195 static class DumpState {
12196 public static final int DUMP_LIBS = 1 << 0;
12197 public static final int DUMP_FEATURES = 1 << 1;
12198 public static final int DUMP_RESOLVERS = 1 << 2;
12199 public static final int DUMP_PERMISSIONS = 1 << 3;
12200 public static final int DUMP_PACKAGES = 1 << 4;
12201 public static final int DUMP_SHARED_USERS = 1 << 5;
12202 public static final int DUMP_MESSAGES = 1 << 6;
12203 public static final int DUMP_PROVIDERS = 1 << 7;
12204 public static final int DUMP_VERIFIERS = 1 << 8;
12205 public static final int DUMP_PREFERRED = 1 << 9;
12206 public static final int DUMP_PREFERRED_XML = 1 << 10;
12207 public static final int DUMP_KEYSETS = 1 << 11;
12208 public static final int DUMP_VERSION = 1 << 12;
12209 public static final int DUMP_INSTALLS = 1 << 13;
12211 public static final int OPTION_SHOW_FILTERS = 1 << 0;
12213 private int mTypes;
12215 private int mOptions;
12217 private boolean mTitlePrinted;
12219 private SharedUserSetting mSharedUser;
12221 public boolean isDumping(int type) {
12222 if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
12226 return (mTypes & type) != 0;
12229 public void setDump(int type) {
12233 public boolean isOptionEnabled(int option) {
12234 return (mOptions & option) != 0;
12237 public void setOptionEnabled(int option) {
12238 mOptions |= option;
12241 public boolean onTitlePrinted() {
12242 final boolean printed = mTitlePrinted;
12243 mTitlePrinted = true;
12247 public boolean getTitlePrinted() {
12248 return mTitlePrinted;
12251 public void setTitlePrinted(boolean enabled) {
12252 mTitlePrinted = enabled;
12255 public SharedUserSetting getSharedUser() {
12256 return mSharedUser;
12259 public void setSharedUser(SharedUserSetting user) {
12260 mSharedUser = user;
12265 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12266 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
12267 != PackageManager.PERMISSION_GRANTED) {
12268 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12269 + Binder.getCallingPid()
12270 + ", uid=" + Binder.getCallingUid()
12271 + " without permission "
12272 + android.Manifest.permission.DUMP);
12276 DumpState dumpState = new DumpState();
12277 boolean fullPreferred = false;
12278 boolean checkin = false;
12280 String packageName = null;
12283 while (opti < args.length) {
12284 String opt = args[opti];
12285 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12290 if ("-a".equals(opt)) {
12291 // Right now we only know how to print all.
12292 } else if ("-h".equals(opt)) {
12293 pw.println("Package manager dump options:");
12294 pw.println(" [-h] [-f] [--checkin] [cmd] ...");
12295 pw.println(" --checkin: dump for a checkin");
12296 pw.println(" -f: print details of intent filters");
12297 pw.println(" -h: print this help");
12298 pw.println(" cmd may be one of:");
12299 pw.println(" l[ibraries]: list known shared libraries");
12300 pw.println(" f[ibraries]: list device features");
12301 pw.println(" k[eysets]: print known keysets");
12302 pw.println(" r[esolvers]: dump intent resolvers");
12303 pw.println(" perm[issions]: dump permissions");
12304 pw.println(" pref[erred]: print preferred package settings");
12305 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
12306 pw.println(" prov[iders]: dump content providers");
12307 pw.println(" p[ackages]: dump installed packages");
12308 pw.println(" s[hared-users]: dump shared user IDs");
12309 pw.println(" m[essages]: print collected runtime messages");
12310 pw.println(" v[erifiers]: print package verifier info");
12311 pw.println(" version: print database version info");
12312 pw.println(" write: write current settings now");
12313 pw.println(" <package.name>: info about given package");
12314 pw.println(" installs: details about install sessions");
12316 } else if ("--checkin".equals(opt)) {
12318 } else if ("-f".equals(opt)) {
12319 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12321 pw.println("Unknown argument: " + opt + "; use -h for help");
12325 // Is the caller requesting to dump a particular piece of data?
12326 if (opti < args.length) {
12327 String cmd = args[opti];
12329 // Is this a package name?
12330 if ("android".equals(cmd) || cmd.contains(".")) {
12332 // When dumping a single package, we always dump all of its
12333 // filter information since the amount of data will be reasonable.
12334 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12335 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
12336 dumpState.setDump(DumpState.DUMP_LIBS);
12337 } else if ("f".equals(cmd) || "features".equals(cmd)) {
12338 dumpState.setDump(DumpState.DUMP_FEATURES);
12339 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
12340 dumpState.setDump(DumpState.DUMP_RESOLVERS);
12341 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
12342 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
12343 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
12344 dumpState.setDump(DumpState.DUMP_PREFERRED);
12345 } else if ("preferred-xml".equals(cmd)) {
12346 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
12347 if (opti < args.length && "--full".equals(args[opti])) {
12348 fullPreferred = true;
12351 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
12352 dumpState.setDump(DumpState.DUMP_PACKAGES);
12353 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
12354 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
12355 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
12356 dumpState.setDump(DumpState.DUMP_PROVIDERS);
12357 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
12358 dumpState.setDump(DumpState.DUMP_MESSAGES);
12359 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
12360 dumpState.setDump(DumpState.DUMP_VERIFIERS);
12361 } else if ("version".equals(cmd)) {
12362 dumpState.setDump(DumpState.DUMP_VERSION);
12363 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
12364 dumpState.setDump(DumpState.DUMP_KEYSETS);
12365 } else if ("installs".equals(cmd)) {
12366 dumpState.setDump(DumpState.DUMP_INSTALLS);
12367 } else if ("write".equals(cmd)) {
12368 synchronized (mPackages) {
12369 mSettings.writeLPr();
12370 pw.println("Settings written.");
12377 pw.println("vers,1");
12381 synchronized (mPackages) {
12382 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
12384 if (dumpState.onTitlePrinted())
12386 pw.println("Database versions:");
12387 pw.print(" SDK Version:");
12388 pw.print(" internal=");
12389 pw.print(mSettings.mInternalSdkPlatform);
12390 pw.print(" external=");
12391 pw.println(mSettings.mExternalSdkPlatform);
12392 pw.print(" DB Version:");
12393 pw.print(" internal=");
12394 pw.print(mSettings.mInternalDatabaseVersion);
12395 pw.print(" external=");
12396 pw.println(mSettings.mExternalDatabaseVersion);
12400 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
12402 if (dumpState.onTitlePrinted())
12404 pw.println("Verifiers:");
12405 pw.print(" Required: ");
12406 pw.print(mRequiredVerifierPackage);
12407 pw.print(" (uid=");
12408 pw.print(getPackageUid(mRequiredVerifierPackage, 0));
12410 } else if (mRequiredVerifierPackage != null) {
12411 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
12412 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
12416 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
12417 boolean printedHeader = false;
12418 final Iterator<String> it = mSharedLibraries.keySet().iterator();
12419 while (it.hasNext()) {
12420 String name = it.next();
12421 SharedLibraryEntry ent = mSharedLibraries.get(name);
12423 if (!printedHeader) {
12424 if (dumpState.onTitlePrinted())
12426 pw.println("Libraries:");
12427 printedHeader = true;
12437 if (ent.path != null) {
12439 pw.print("(jar) ");
12440 pw.print(ent.path);
12443 pw.print(ent.path);
12447 pw.print("(apk) ");
12458 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
12459 if (dumpState.onTitlePrinted())
12462 pw.println("Features:");
12464 Iterator<String> it = mAvailableFeatures.keySet().iterator();
12465 while (it.hasNext()) {
12466 String name = it.next();
12476 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
12477 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
12478 : "Activity Resolver Table:", " ", packageName,
12479 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12480 dumpState.setTitlePrinted(true);
12482 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
12483 : "Receiver Resolver Table:", " ", packageName,
12484 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12485 dumpState.setTitlePrinted(true);
12487 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
12488 : "Service Resolver Table:", " ", packageName,
12489 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12490 dumpState.setTitlePrinted(true);
12492 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
12493 : "Provider Resolver Table:", " ", packageName,
12494 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12495 dumpState.setTitlePrinted(true);
12499 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
12500 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12501 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12502 int user = mSettings.mPreferredActivities.keyAt(i);
12504 dumpState.getTitlePrinted()
12505 ? "\nPreferred Activities User " + user + ":"
12506 : "Preferred Activities User " + user + ":", " ",
12507 packageName, true)) {
12508 dumpState.setTitlePrinted(true);
12513 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
12515 FileOutputStream fout = new FileOutputStream(fd);
12516 BufferedOutputStream str = new BufferedOutputStream(fout);
12517 XmlSerializer serializer = new FastXmlSerializer();
12519 serializer.setOutput(str, "utf-8");
12520 serializer.startDocument(null, true);
12521 serializer.setFeature(
12522 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
12523 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
12524 serializer.endDocument();
12525 serializer.flush();
12526 } catch (IllegalArgumentException e) {
12527 pw.println("Failed writing: " + e);
12528 } catch (IllegalStateException e) {
12529 pw.println("Failed writing: " + e);
12530 } catch (IOException e) {
12531 pw.println("Failed writing: " + e);
12535 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
12536 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
12537 if (packageName == null) {
12538 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
12540 if (dumpState.onTitlePrinted())
12542 pw.println("AppOp Permissions:");
12544 pw.print(" AppOp Permission ");
12545 pw.print(mAppOpPermissionPackages.keyAt(iperm));
12547 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
12548 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
12549 pw.print(" "); pw.println(pkgs.valueAt(ipkg));
12555 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
12556 boolean printedSomething = false;
12557 for (PackageParser.Provider p : mProviders.mProviders.values()) {
12558 if (packageName != null && !packageName.equals(p.info.packageName)) {
12561 if (!printedSomething) {
12562 if (dumpState.onTitlePrinted())
12564 pw.println("Registered ContentProviders:");
12565 printedSomething = true;
12567 pw.print(" "); p.printComponentShortName(pw); pw.println(":");
12568 pw.print(" "); pw.println(p.toString());
12570 printedSomething = false;
12571 for (Map.Entry<String, PackageParser.Provider> entry :
12572 mProvidersByAuthority.entrySet()) {
12573 PackageParser.Provider p = entry.getValue();
12574 if (packageName != null && !packageName.equals(p.info.packageName)) {
12577 if (!printedSomething) {
12578 if (dumpState.onTitlePrinted())
12580 pw.println("ContentProvider Authorities:");
12581 printedSomething = true;
12583 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
12584 pw.print(" "); pw.println(p.toString());
12585 if (p.info != null && p.info.applicationInfo != null) {
12586 final String appInfo = p.info.applicationInfo.toString();
12587 pw.print(" applicationInfo="); pw.println(appInfo);
12592 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
12593 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
12596 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
12597 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
12600 if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
12601 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
12604 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
12605 // XXX should handle packageName != null by dumping only install data that
12606 // the given package is involved with.
12607 if (dumpState.onTitlePrinted()) pw.println();
12608 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
12611 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
12612 if (dumpState.onTitlePrinted()) pw.println();
12613 mSettings.dumpReadMessagesLPr(pw, dumpState);
12616 pw.println("Package warning messages:");
12617 final File fname = getSettingsProblemFile();
12618 FileInputStream in = null;
12620 in = new FileInputStream(fname);
12621 final int avail = in.available();
12622 final byte[] data = new byte[avail];
12624 pw.print(new String(data));
12625 } catch (FileNotFoundException e) {
12626 } catch (IOException e) {
12631 } catch (IOException e) {
12637 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
12638 BufferedReader in = null;
12639 String line = null;
12641 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
12642 while ((line = in.readLine()) != null) {
12646 } catch (IOException ignored) {
12648 IoUtils.closeQuietly(in);
12654 // ------- apps on sdcard specific code -------
12655 static final boolean DEBUG_SD_INSTALL = false;
12657 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
12659 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
12661 private boolean mMediaMounted = false;
12663 static String getEncryptKey() {
12665 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
12666 SD_ENCRYPTION_KEYSTORE_NAME);
12667 if (sdEncKey == null) {
12668 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
12669 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
12670 if (sdEncKey == null) {
12671 Slog.e(TAG, "Failed to create encryption keys");
12676 } catch (NoSuchAlgorithmException nsae) {
12677 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
12679 } catch (IOException ioe) {
12680 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
12686 * Update media status on PackageManager.
12689 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
12690 int callingUid = Binder.getCallingUid();
12691 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12692 throw new SecurityException("Media status can only be updated by the system");
12694 // reader; this apparently protects mMediaMounted, but should probably
12695 // be a different lock in that case.
12696 synchronized (mPackages) {
12697 Log.i(TAG, "Updating external media status from "
12698 + (mMediaMounted ? "mounted" : "unmounted") + " to "
12699 + (mediaStatus ? "mounted" : "unmounted"));
12700 if (DEBUG_SD_INSTALL)
12701 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
12702 + ", mMediaMounted=" + mMediaMounted);
12703 if (mediaStatus == mMediaMounted) {
12704 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
12706 mHandler.sendMessage(msg);
12709 mMediaMounted = mediaStatus;
12711 // Queue up an async operation since the package installation may take a
12713 mHandler.post(new Runnable() {
12714 public void run() {
12715 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
12721 * Called by MountService when the initial ASECs to scan are available.
12722 * Should block until all the ASEC containers are finished being scanned.
12724 public void scanAvailableAsecs() {
12725 updateExternalMediaStatusInner(true, false, false);
12726 if (mShouldRestoreconData) {
12727 SELinuxMMAC.setRestoreconDone();
12728 mShouldRestoreconData = false;
12733 * Collect information of applications on external media, map them against
12734 * existing containers and update information based on current mount status.
12735 * Please note that we always have to report status if reportStatus has been
12736 * set to true especially when unloading packages.
12738 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
12739 boolean externalStorage) {
12740 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
12741 int[] uidArr = EmptyArray.INT;
12743 final String[] list = PackageHelper.getSecureContainerList();
12744 if (ArrayUtils.isEmpty(list)) {
12745 Log.i(TAG, "No secure containers found");
12747 // Process list of secure containers and categorize them
12748 // as active or stale based on their package internal state.
12751 synchronized (mPackages) {
12752 for (String cid : list) {
12753 // Leave stages untouched for now; installer service owns them
12754 if (PackageInstallerService.isStageName(cid)) continue;
12756 if (DEBUG_SD_INSTALL)
12757 Log.i(TAG, "Processing container " + cid);
12758 String pkgName = getAsecPackageName(cid);
12759 if (pkgName == null) {
12760 Slog.i(TAG, "Found stale container " + cid + " with no package name");
12763 if (DEBUG_SD_INSTALL)
12764 Log.i(TAG, "Looking for pkg : " + pkgName);
12766 final PackageSetting ps = mSettings.mPackages.get(pkgName);
12768 Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
12773 * Skip packages that are not external if we're unmounting
12774 * external storage.
12776 if (externalStorage && !isMounted && !isExternal(ps)) {
12780 final AsecInstallArgs args = new AsecInstallArgs(cid,
12781 getAppDexInstructionSets(ps), isForwardLocked(ps));
12782 // The package status is changed only if the code path
12783 // matches between settings and the container id.
12784 if (ps.codePathString != null
12785 && ps.codePathString.startsWith(args.getCodePath())) {
12786 if (DEBUG_SD_INSTALL) {
12787 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
12788 + " at code path: " + ps.codePathString);
12791 // We do have a valid package installed on sdcard
12792 processCids.put(args, ps.codePathString);
12793 final int uid = ps.appId;
12795 uidArr = ArrayUtils.appendInt(uidArr, uid);
12798 Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
12799 + ps.codePathString);
12804 Arrays.sort(uidArr);
12807 // Process packages with valid entries.
12809 if (DEBUG_SD_INSTALL)
12810 Log.i(TAG, "Loading packages");
12811 loadMediaPackages(processCids, uidArr);
12812 startCleaningPackages();
12813 mInstallerService.onSecureContainersAvailable();
12815 if (DEBUG_SD_INSTALL)
12816 Log.i(TAG, "Unloading packages");
12817 unloadMediaPackages(processCids, uidArr, reportStatus);
12821 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
12822 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
12823 int size = pkgList.size();
12825 // Send broadcasts here
12826 Bundle extras = new Bundle();
12827 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
12828 .toArray(new String[size]));
12829 if (uidArr != null) {
12830 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
12833 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
12835 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
12836 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
12837 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
12842 * Look at potentially valid container ids from processCids If package
12843 * information doesn't match the one on record or package scanning fails,
12844 * the cid is added to list of removeCids. We currently don't delete stale
12847 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
12848 ArrayList<String> pkgList = new ArrayList<String>();
12849 Set<AsecInstallArgs> keys = processCids.keySet();
12851 for (AsecInstallArgs args : keys) {
12852 String codePath = processCids.get(args);
12853 if (DEBUG_SD_INSTALL)
12854 Log.i(TAG, "Loading container : " + args.cid);
12855 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12857 // Make sure there are no container errors first.
12858 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
12859 Slog.e(TAG, "Failed to mount cid : " + args.cid
12860 + " when installing from sdcard");
12863 // Check code path here.
12864 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
12865 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
12866 + " does not match one in settings " + codePath);
12870 int parseFlags = mDefParseFlags;
12871 if (args.isExternal()) {
12872 parseFlags |= PackageParser.PARSE_ON_SDCARD;
12874 if (args.isFwdLocked()) {
12875 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
12878 synchronized (mInstallLock) {
12879 PackageParser.Package pkg = null;
12881 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
12882 } catch (PackageManagerException e) {
12883 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
12885 // Scan the package
12888 * TODO why is the lock being held? doPostInstall is
12889 * called in other places without the lock. This needs
12890 * to be straightened out.
12893 synchronized (mPackages) {
12894 retCode = PackageManager.INSTALL_SUCCEEDED;
12895 pkgList.add(pkg.packageName);
12896 // Post process args
12897 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
12898 pkg.applicationInfo.uid);
12901 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard");
12906 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
12907 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
12912 synchronized (mPackages) {
12913 // If the platform SDK has changed since the last time we booted,
12914 // we need to re-grant app permission to catch any new ones that
12915 // appear. This is really a hack, and means that apps can in some
12916 // cases get permissions that the user didn't initially explicitly
12917 // allow... it would be nice to have some better way to handle
12919 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
12920 if (regrantPermissions)
12921 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
12922 + mSdkVersion + "; regranting permissions for external storage");
12923 mSettings.mExternalSdkPlatform = mSdkVersion;
12925 // Make sure group IDs have been assigned, and any permission
12926 // changes in other apps are accounted for
12927 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
12928 | (regrantPermissions
12929 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
12932 mSettings.updateExternalDatabaseVersion();
12934 // can downgrade to reader
12935 // Persist settings
12936 mSettings.writeLPr();
12938 // Send a broadcast to let everyone know we are done processing
12939 if (pkgList.size() > 0) {
12940 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
12945 * Utility method to unload a list of specified containers
12947 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
12948 // Just unmount all valid containers.
12949 for (AsecInstallArgs arg : cidArgs) {
12950 synchronized (mInstallLock) {
12951 arg.doPostDeleteLI(false);
12957 * Unload packages mounted on external media. This involves deleting package
12958 * data from internal structures, sending broadcasts about diabled packages,
12959 * gc'ing to free up references, unmounting all secure containers
12960 * corresponding to packages on external media, and posting a
12961 * UPDATED_MEDIA_STATUS message if status has been requested. Please note
12962 * that we always have to post this message if status has been requested no
12965 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
12966 final boolean reportStatus) {
12967 if (DEBUG_SD_INSTALL)
12968 Log.i(TAG, "unloading media packages");
12969 ArrayList<String> pkgList = new ArrayList<String>();
12970 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
12971 final Set<AsecInstallArgs> keys = processCids.keySet();
12972 for (AsecInstallArgs args : keys) {
12973 String pkgName = args.getPackageName();
12974 if (DEBUG_SD_INSTALL)
12975 Log.i(TAG, "Trying to unload pkg : " + pkgName);
12976 // Delete package internally
12977 PackageRemovedInfo outInfo = new PackageRemovedInfo();
12978 synchronized (mInstallLock) {
12979 boolean res = deletePackageLI(pkgName, null, false, null, null,
12980 PackageManager.DELETE_KEEP_DATA, outInfo, false);
12982 pkgList.add(pkgName);
12984 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
12985 failedList.add(args);
12991 synchronized (mPackages) {
12992 // We didn't update the settings after removing each package;
12993 // write them now for all packages.
12994 mSettings.writeLPr();
12997 // We have to absolutely send UPDATED_MEDIA_STATUS only
12998 // after confirming that all the receivers processed the ordered
12999 // broadcast when packages get disabled, force a gc to clean things up.
13000 // and unload all the containers.
13001 if (pkgList.size() > 0) {
13002 sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
13003 new IIntentReceiver.Stub() {
13004 public void performReceive(Intent intent, int resultCode, String data,
13005 Bundle extras, boolean ordered, boolean sticky,
13006 int sendingUser) throws RemoteException {
13007 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
13008 reportStatus ? 1 : 0, 1, keys);
13009 mHandler.sendMessage(msg);
13013 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
13015 mHandler.sendMessage(msg);
13021 public void movePackage(final String packageName, final IPackageMoveObserver observer,
13023 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
13024 UserHandle user = new UserHandle(UserHandle.getCallingUserId());
13025 int returnCode = PackageManager.MOVE_SUCCEEDED;
13026 int currInstallFlags = 0;
13027 int newInstallFlags = 0;
13029 File codeFile = null;
13030 String installerPackageName = null;
13031 String packageAbiOverride = null;
13034 synchronized (mPackages) {
13035 final PackageParser.Package pkg = mPackages.get(packageName);
13036 final PackageSetting ps = mSettings.mPackages.get(packageName);
13037 if (pkg == null || ps == null) {
13038 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
13040 // Disable moving fwd locked apps and system packages
13041 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
13042 Slog.w(TAG, "Cannot move system application");
13043 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
13044 } else if (pkg.mOperationPending) {
13045 Slog.w(TAG, "Attempt to move package which has pending operations");
13046 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
13048 // Find install location first
13049 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13050 && (flags & PackageManager.MOVE_INTERNAL) != 0) {
13051 Slog.w(TAG, "Ambigous flags specified for move location.");
13052 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13054 newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13055 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13056 currInstallFlags = isExternal(pkg)
13057 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13059 if (newInstallFlags == currInstallFlags) {
13060 Slog.w(TAG, "No move required. Trying to move to same location");
13061 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13063 if (isForwardLocked(pkg)) {
13064 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13065 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13069 if (returnCode == PackageManager.MOVE_SUCCEEDED) {
13070 pkg.mOperationPending = true;
13074 codeFile = new File(pkg.codePath);
13075 installerPackageName = ps.installerPackageName;
13076 packageAbiOverride = ps.cpuAbiOverrideString;
13080 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
13082 observer.packageMoved(packageName, returnCode);
13083 } catch (RemoteException ignored) {
13088 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
13090 public void onUserActionRequired(Intent intent) throws RemoteException {
13091 throw new IllegalStateException();
13095 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
13096 Bundle extras) throws RemoteException {
13097 Slog.d(TAG, "Install result for move: "
13098 + PackageManager.installStatusToString(returnCode, msg));
13100 // We usually have a new package now after the install, but if
13101 // we failed we need to clear the pending flag on the original
13103 synchronized (mPackages) {
13104 final PackageParser.Package pkg = mPackages.get(packageName);
13106 pkg.mOperationPending = false;
13110 final int status = PackageManager.installStatusToPublicStatus(returnCode);
13112 case PackageInstaller.STATUS_SUCCESS:
13113 observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
13115 case PackageInstaller.STATUS_FAILURE_STORAGE:
13116 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
13119 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
13125 // Treat a move like reinstalling an existing app, which ensures that we
13126 // process everythign uniformly, like unpacking native libraries.
13127 newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
13129 final Message msg = mHandler.obtainMessage(INIT_COPY);
13130 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
13131 msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
13132 installerPackageName, null, user, packageAbiOverride);
13133 mHandler.sendMessage(msg);
13137 public boolean setInstallLocation(int loc) {
13138 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
13140 if (getInstallLocation() == loc) {
13143 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
13144 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
13145 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
13146 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
13153 public int getInstallLocation() {
13154 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13155 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
13156 PackageHelper.APP_INSTALL_AUTO);
13159 /** Called by UserManagerService */
13160 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
13161 mDirtyUsers.remove(userHandle);
13162 mSettings.removeUserLPw(userHandle);
13163 mPendingBroadcasts.remove(userHandle);
13164 if (mInstaller != null) {
13165 // Technically, we shouldn't be doing this with the package lock
13166 // held. However, this is very rare, and there is already so much
13167 // other disk I/O going on, that we'll let it slide for now.
13168 mInstaller.removeUserDataDirs(userHandle);
13170 mUserNeedsBadging.delete(userHandle);
13171 removeUnusedPackagesLILPw(userManager, userHandle);
13175 * We're removing userHandle and would like to remove any downloaded packages
13176 * that are no longer in use by any other user.
13177 * @param userHandle the user being removed
13179 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
13180 final boolean DEBUG_CLEAN_APKS = false;
13181 int [] users = userManager.getUserIdsLPr();
13182 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
13183 while (psit.hasNext()) {
13184 PackageSetting ps = psit.next();
13185 if (ps.pkg == null) {
13188 final String packageName = ps.pkg.packageName;
13189 // Skip over if system app
13190 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13193 if (DEBUG_CLEAN_APKS) {
13194 Slog.i(TAG, "Checking package " + packageName);
13196 boolean keep = false;
13197 for (int i = 0; i < users.length; i++) {
13198 if (users[i] != userHandle && ps.getInstalled(users[i])) {
13200 if (DEBUG_CLEAN_APKS) {
13201 Slog.i(TAG, " Keeping package " + packageName + " for user "
13208 if (DEBUG_CLEAN_APKS) {
13209 Slog.i(TAG, " Removing package " + packageName);
13211 mHandler.post(new Runnable() {
13212 public void run() {
13213 deletePackageX(packageName, userHandle, 0);
13220 /** Called by UserManagerService */
13221 void createNewUserLILPw(int userHandle, File path) {
13222 if (mInstaller != null) {
13223 mInstaller.createUserConfig(userHandle);
13224 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
13229 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
13230 mContext.enforceCallingOrSelfPermission(
13231 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13232 "Only package verification agents can read the verifier device identity");
13234 synchronized (mPackages) {
13235 return mSettings.getVerifierDeviceIdentityLPw();
13240 public void setPermissionEnforced(String permission, boolean enforced) {
13241 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
13242 if (READ_EXTERNAL_STORAGE.equals(permission)) {
13243 synchronized (mPackages) {
13244 if (mSettings.mReadExternalStorageEnforced == null
13245 || mSettings.mReadExternalStorageEnforced != enforced) {
13246 mSettings.mReadExternalStorageEnforced = enforced;
13247 mSettings.writeLPr();
13250 // kill any non-foreground processes so we restart them and
13251 // grant/revoke the GID.
13252 final IActivityManager am = ActivityManagerNative.getDefault();
13254 final long token = Binder.clearCallingIdentity();
13256 am.killProcessesBelowForeground("setPermissionEnforcement");
13257 } catch (RemoteException e) {
13259 Binder.restoreCallingIdentity(token);
13263 throw new IllegalArgumentException("No selective enforcement for " + permission);
13269 public boolean isPermissionEnforced(String permission) {
13274 public boolean isStorageLow() {
13275 final long token = Binder.clearCallingIdentity();
13277 final DeviceStorageMonitorInternal
13278 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13280 return dsm.isMemoryLow();
13285 Binder.restoreCallingIdentity(token);
13290 public IPackageInstaller getPackageInstaller() {
13291 return mInstallerService;
13294 private boolean userNeedsBadging(int userId) {
13295 int index = mUserNeedsBadging.indexOfKey(userId);
13297 final UserInfo userInfo;
13298 final long token = Binder.clearCallingIdentity();
13300 userInfo = sUserManager.getUserInfo(userId);
13302 Binder.restoreCallingIdentity(token);
13305 if (userInfo != null && userInfo.isManagedProfile()) {
13310 mUserNeedsBadging.put(userId, b);
13313 return mUserNeedsBadging.valueAt(index);
13317 public KeySet getKeySetByAlias(String packageName, String alias) {
13318 if (packageName == null || alias == null) {
13321 synchronized(mPackages) {
13322 final PackageParser.Package pkg = mPackages.get(packageName);
13324 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13325 throw new IllegalArgumentException("Unknown package: " + packageName);
13327 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13328 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
13333 public KeySet getSigningKeySet(String packageName) {
13334 if (packageName == null) {
13337 synchronized(mPackages) {
13338 final PackageParser.Package pkg = mPackages.get(packageName);
13340 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13341 throw new IllegalArgumentException("Unknown package: " + packageName);
13343 if (pkg.applicationInfo.uid != Binder.getCallingUid()
13344 && Process.SYSTEM_UID != Binder.getCallingUid()) {
13345 throw new SecurityException("May not access signing KeySet of other apps.");
13347 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13348 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
13353 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
13354 if (packageName == null || ks == null) {
13357 synchronized(mPackages) {
13358 final PackageParser.Package pkg = mPackages.get(packageName);
13360 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13361 throw new IllegalArgumentException("Unknown package: " + packageName);
13363 IBinder ksh = ks.getToken();
13364 if (ksh instanceof KeySetHandle) {
13365 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13366 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
13373 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
13374 if (packageName == null || ks == null) {
13377 synchronized(mPackages) {
13378 final PackageParser.Package pkg = mPackages.get(packageName);
13380 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13381 throw new IllegalArgumentException("Unknown package: " + packageName);
13383 IBinder ksh = ks.getToken();
13384 if (ksh instanceof KeySetHandle) {
13385 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13386 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);