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.app.usage.UsageStats;
88 import android.app.usage.UsageStatsManager;
89 import android.content.BroadcastReceiver;
90 import android.content.ComponentName;
91 import android.content.Context;
92 import android.content.IIntentReceiver;
93 import android.content.Intent;
94 import android.content.IntentFilter;
95 import android.content.IntentSender;
96 import android.content.IntentSender.SendIntentException;
97 import android.content.ServiceConnection;
98 import android.content.pm.ActivityInfo;
99 import android.content.pm.ApplicationInfo;
100 import android.content.pm.FeatureInfo;
101 import android.content.pm.IPackageDataObserver;
102 import android.content.pm.IPackageDeleteObserver;
103 import android.content.pm.IPackageDeleteObserver2;
104 import android.content.pm.IPackageInstallObserver2;
105 import android.content.pm.IPackageInstaller;
106 import android.content.pm.IPackageManager;
107 import android.content.pm.IPackageMoveObserver;
108 import android.content.pm.IPackageStatsObserver;
109 import android.content.pm.InstrumentationInfo;
110 import android.content.pm.KeySet;
111 import android.content.pm.ManifestDigest;
112 import android.content.pm.PackageCleanItem;
113 import android.content.pm.PackageInfo;
114 import android.content.pm.PackageInfoLite;
115 import android.content.pm.PackageInstaller;
116 import android.content.pm.PackageManager;
117 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
118 import android.content.pm.PackageParser.ActivityIntentInfo;
119 import android.content.pm.PackageParser.PackageLite;
120 import android.content.pm.PackageParser.PackageParserException;
121 import android.content.pm.PackageParser;
122 import android.content.pm.PackageStats;
123 import android.content.pm.PackageUserState;
124 import android.content.pm.ParceledListSlice;
125 import android.content.pm.PermissionGroupInfo;
126 import android.content.pm.PermissionInfo;
127 import android.content.pm.ProviderInfo;
128 import android.content.pm.ResolveInfo;
129 import android.content.pm.ServiceInfo;
130 import android.content.pm.Signature;
131 import android.content.pm.UserInfo;
132 import android.content.pm.VerificationParams;
133 import android.content.pm.VerifierDeviceIdentity;
134 import android.content.pm.VerifierInfo;
135 import android.content.res.Resources;
136 import android.hardware.display.DisplayManager;
137 import android.net.Uri;
138 import android.os.Binder;
139 import android.os.Build;
140 import android.os.Bundle;
141 import android.os.Environment;
142 import android.os.Environment.UserEnvironment;
143 import android.os.storage.StorageManager;
144 import android.os.Debug;
145 import android.os.FileUtils;
146 import android.os.Handler;
147 import android.os.IBinder;
148 import android.os.Looper;
149 import android.os.Message;
150 import android.os.Parcel;
151 import android.os.ParcelFileDescriptor;
152 import android.os.Process;
153 import android.os.RemoteException;
154 import android.os.SELinux;
155 import android.os.ServiceManager;
156 import android.os.SystemClock;
157 import android.os.SystemProperties;
158 import android.os.UserHandle;
159 import android.os.UserManager;
160 import android.security.KeyStore;
161 import android.security.SystemKeyStore;
162 import android.system.ErrnoException;
163 import android.system.Os;
164 import android.system.StructStat;
165 import android.text.TextUtils;
166 import android.util.ArraySet;
167 import android.util.AtomicFile;
168 import android.util.DisplayMetrics;
169 import android.util.EventLog;
170 import android.util.ExceptionUtils;
171 import android.util.Log;
172 import android.util.LogPrinter;
173 import android.util.PrintStreamPrinter;
174 import android.util.Slog;
175 import android.util.SparseArray;
176 import android.util.SparseBooleanArray;
177 import android.view.Display;
179 import java.io.BufferedInputStream;
180 import java.io.BufferedOutputStream;
181 import java.io.BufferedReader;
183 import java.io.FileDescriptor;
184 import java.io.FileInputStream;
185 import java.io.FileNotFoundException;
186 import java.io.FileOutputStream;
187 import java.io.FileReader;
188 import java.io.FilenameFilter;
189 import java.io.IOException;
190 import java.io.InputStream;
191 import java.io.PrintWriter;
192 import java.nio.charset.StandardCharsets;
193 import java.security.NoSuchAlgorithmException;
194 import java.security.PublicKey;
195 import java.security.cert.CertificateEncodingException;
196 import java.security.cert.CertificateException;
197 import java.text.SimpleDateFormat;
198 import java.util.ArrayList;
199 import java.util.Arrays;
200 import java.util.Collection;
201 import java.util.Collections;
202 import java.util.Comparator;
203 import java.util.Date;
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 long mDexOptLRUThresholdInMills;
333 final DisplayMetrics mMetrics;
334 final int mDefParseFlags;
335 final String[] mSeparateProcesses;
336 final boolean mIsUpgrade;
338 // This is where all application persistent data goes.
339 final File mAppDataDir;
341 // This is where all application persistent data goes for secondary users.
342 final File mUserAppDataDir;
344 /** The location for ASEC container files on internal storage. */
345 final String mAsecInternalPath;
347 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
348 // LOCK HELD. Can be called with mInstallLock held.
349 final Installer mInstaller;
351 /** Directory where installed third-party apps stored */
352 final File mAppInstallDir;
355 * Directory to which applications installed internally have their
356 * 32 bit native libraries copied.
358 private File mAppLib32InstallDir;
360 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
362 final File mDrmAppPrivateInstallDir;
364 // ----------------------------------------------------------------
366 // Lock for state used when installing and doing other long running
367 // operations. Methods that must be called with this lock held have
369 final Object mInstallLock = new Object();
371 // ----------------------------------------------------------------
373 // Keys are String (package name), values are Package. This also serves
374 // as the lock for the global state. Methods that must be called with
375 // this lock held have the prefix "LP".
376 final ArrayMap<String, PackageParser.Package> mPackages =
377 new ArrayMap<String, PackageParser.Package>();
379 // Tracks available target package names -> overlay package paths.
380 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
381 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
383 final Settings mSettings;
384 boolean mRestoredSettings;
386 // System configuration read by SystemConfig.
387 final int[] mGlobalGids;
388 final SparseArray<ArraySet<String>> mSystemPermissions;
389 final ArrayMap<String, FeatureInfo> mAvailableFeatures;
391 // If mac_permissions.xml was found for seinfo labeling.
392 boolean mFoundPolicyFile;
394 // If a recursive restorecon of /data/data/<pkg> is needed.
395 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
397 public static final class SharedLibraryEntry {
398 public final String path;
399 public final String apk;
401 SharedLibraryEntry(String _path, String _apk) {
407 // Currently known shared libraries.
408 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
409 new ArrayMap<String, SharedLibraryEntry>();
411 // All available activities, for your resolving pleasure.
412 final ActivityIntentResolver mActivities =
413 new ActivityIntentResolver();
415 // All available receivers, for your resolving pleasure.
416 final ActivityIntentResolver mReceivers =
417 new ActivityIntentResolver();
419 // All available services, for your resolving pleasure.
420 final ServiceIntentResolver mServices = new ServiceIntentResolver();
422 // All available providers, for your resolving pleasure.
423 final ProviderIntentResolver mProviders = new ProviderIntentResolver();
425 // Mapping from provider base names (first directory in content URI codePath)
426 // to the provider information.
427 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
428 new ArrayMap<String, PackageParser.Provider>();
430 // Mapping from instrumentation class names to info about them.
431 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
432 new ArrayMap<ComponentName, PackageParser.Instrumentation>();
434 // Mapping from permission names to info about them.
435 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
436 new ArrayMap<String, PackageParser.PermissionGroup>();
438 // Packages whose data we have transfered into another package, thus
439 // should no longer exist.
440 final ArraySet<String> mTransferedPackages = new ArraySet<String>();
442 // Broadcast actions that are only available to the system.
443 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
445 /** List of packages waiting for verification. */
446 final SparseArray<PackageVerificationState> mPendingVerification
447 = new SparseArray<PackageVerificationState>();
449 /** Set of packages associated with each app op permission. */
450 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
452 final PackageInstallerService mInstallerService;
454 ArraySet<PackageParser.Package> mDeferredDexOpt = null;
456 // Cache of users who need badging.
457 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
459 /** Token for keys in mPendingVerification. */
460 private int mPendingVerificationToken = 0;
462 volatile boolean mSystemReady;
463 volatile boolean mSafeMode;
464 volatile boolean mHasSystemUidErrors;
466 ApplicationInfo mAndroidApplication;
467 final ActivityInfo mResolveActivity = new ActivityInfo();
468 final ResolveInfo mResolveInfo = new ResolveInfo();
469 ComponentName mResolveComponentName;
470 PackageParser.Package mPlatformPackage;
471 ComponentName mCustomResolverComponentName;
473 boolean mResolverReplaced = false;
475 // Set of pending broadcasts for aggregating enable/disable of components.
476 static class PendingPackageBroadcasts {
477 // for each user id, a map of <package name -> components within that package>
478 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
480 public PendingPackageBroadcasts() {
481 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
484 public ArrayList<String> get(int userId, String packageName) {
485 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
486 return packages.get(packageName);
489 public void put(int userId, String packageName, ArrayList<String> components) {
490 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
491 packages.put(packageName, components);
494 public void remove(int userId, String packageName) {
495 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
496 if (packages != null) {
497 packages.remove(packageName);
501 public void remove(int userId) {
502 mUidMap.remove(userId);
505 public int userIdCount() {
506 return mUidMap.size();
509 public int userIdAt(int n) {
510 return mUidMap.keyAt(n);
513 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
514 return mUidMap.get(userId);
518 // total number of pending broadcast entries across all userIds
520 for (int i = 0; i< mUidMap.size(); i++) {
521 num += mUidMap.valueAt(i).size();
526 public void clear() {
530 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
531 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
533 map = new ArrayMap<String, ArrayList<String>>();
534 mUidMap.put(userId, map);
539 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
541 // Service Connection to remote media container service to copy
542 // package uri's from external media onto secure containers
543 // or internal storage.
544 private IMediaContainerService mContainerService = null;
546 static final int SEND_PENDING_BROADCAST = 1;
547 static final int MCS_BOUND = 3;
548 static final int END_COPY = 4;
549 static final int INIT_COPY = 5;
550 static final int MCS_UNBIND = 6;
551 static final int START_CLEANING_PACKAGE = 7;
552 static final int FIND_INSTALL_LOC = 8;
553 static final int POST_INSTALL = 9;
554 static final int MCS_RECONNECT = 10;
555 static final int MCS_GIVE_UP = 11;
556 static final int UPDATED_MEDIA_STATUS = 12;
557 static final int WRITE_SETTINGS = 13;
558 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
559 static final int PACKAGE_VERIFIED = 15;
560 static final int CHECK_PENDING_VERIFICATION = 16;
562 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
564 // Delay time in millisecs
565 static final int BROADCAST_DELAY = 10 * 1000;
567 static UserManagerService sUserManager;
569 // Stores a list of users whose package restrictions file needs to be updated
570 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
572 final private DefaultContainerConnection mDefContainerConn =
573 new DefaultContainerConnection();
574 class DefaultContainerConnection implements ServiceConnection {
575 public void onServiceConnected(ComponentName name, IBinder service) {
576 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
577 IMediaContainerService imcs =
578 IMediaContainerService.Stub.asInterface(service);
579 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
582 public void onServiceDisconnected(ComponentName name) {
583 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
587 // Recordkeeping of restore-after-install operations that are currently in flight
588 // between the Package Manager and the Backup Manager
589 class PostInstallData {
590 public InstallArgs args;
591 public PackageInstalledInfo res;
593 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
598 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
599 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
601 private final String mRequiredVerifierPackage;
603 private final PackageUsage mPackageUsage = new PackageUsage();
605 private class PackageUsage {
606 private static final int WRITE_INTERVAL
607 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
609 private final Object mFileLock = new Object();
610 private final AtomicLong mLastWritten = new AtomicLong(0);
611 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
613 private boolean mIsHistoricalPackageUsageAvailable = true;
615 boolean isHistoricalPackageUsageAvailable() {
616 return mIsHistoricalPackageUsageAvailable;
619 void write(boolean force) {
624 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
628 if (mBackgroundWriteRunning.compareAndSet(false, true)) {
629 new Thread("PackageUsage_DiskWriter") {
635 mBackgroundWriteRunning.set(false);
642 private void writeInternal() {
643 synchronized (mPackages) {
644 synchronized (mFileLock) {
645 AtomicFile file = getFile();
646 FileOutputStream f = null;
648 f = file.startWrite();
649 BufferedOutputStream out = new BufferedOutputStream(f);
650 FileUtils.setPermissions(file.getBaseFile().getPath(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
651 StringBuilder sb = new StringBuilder();
652 for (PackageParser.Package pkg : mPackages.values()) {
653 if (pkg.mLastPackageUsageTimeInMills == 0) {
657 sb.append(pkg.packageName);
659 sb.append((long)pkg.mLastPackageUsageTimeInMills);
661 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
665 } catch (IOException e) {
669 Log.e(TAG, "Failed to write package usage times", e);
673 mLastWritten.set(SystemClock.elapsedRealtime());
677 synchronized (mFileLock) {
678 AtomicFile file = getFile();
679 BufferedInputStream in = null;
681 in = new BufferedInputStream(file.openRead());
682 StringBuffer sb = new StringBuffer();
684 String packageName = readToken(in, sb, ' ');
685 if (packageName == null) {
688 String timeInMillisString = readToken(in, sb, '\n');
689 if (timeInMillisString == null) {
690 throw new IOException("Failed to find last usage time for package "
693 PackageParser.Package pkg = mPackages.get(packageName);
699 timeInMillis = Long.parseLong(timeInMillisString.toString());
700 } catch (NumberFormatException e) {
701 throw new IOException("Failed to parse " + timeInMillisString
704 pkg.mLastPackageUsageTimeInMills = timeInMillis;
706 } catch (FileNotFoundException expected) {
707 mIsHistoricalPackageUsageAvailable = false;
708 } catch (IOException e) {
709 Log.w(TAG, "Failed to read package usage times", e);
711 IoUtils.closeQuietly(in);
714 mLastWritten.set(SystemClock.elapsedRealtime());
717 private String readToken(InputStream in, StringBuffer sb, char endOfToken)
723 if (sb.length() == 0) {
726 throw new IOException("Unexpected EOF");
728 if (ch == endOfToken) {
729 return sb.toString();
735 private AtomicFile getFile() {
736 File dataDir = Environment.getDataDirectory();
737 File systemDir = new File(dataDir, "system");
738 File fname = new File(systemDir, "package-usage.list");
739 return new AtomicFile(fname);
743 class PackageHandler extends Handler {
744 private boolean mBound = false;
745 final ArrayList<HandlerParams> mPendingInstalls =
746 new ArrayList<HandlerParams>();
748 private boolean connectToService() {
749 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
750 " DefaultContainerService");
751 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
752 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
753 if (mContext.bindServiceAsUser(service, mDefContainerConn,
754 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
755 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
759 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
763 private void disconnectService() {
764 mContainerService = null;
766 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
767 mContext.unbindService(mDefContainerConn);
768 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
771 PackageHandler(Looper looper) {
775 public void handleMessage(Message msg) {
777 doHandleMessage(msg);
779 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
783 void doHandleMessage(Message msg) {
786 HandlerParams params = (HandlerParams) msg.obj;
787 int idx = mPendingInstalls.size();
788 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
789 // If a bind was already initiated we dont really
790 // need to do anything. The pending install
791 // will be processed later on.
793 // If this is the only one pending we might
794 // have to bind to the service again.
795 if (!connectToService()) {
796 Slog.e(TAG, "Failed to bind to media container service");
797 params.serviceError();
800 // Once we bind to the service, the first
801 // pending request will be processed.
802 mPendingInstalls.add(idx, params);
805 mPendingInstalls.add(idx, params);
806 // Already bound to the service. Just make
807 // sure we trigger off processing the first request.
809 mHandler.sendEmptyMessage(MCS_BOUND);
815 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
816 if (msg.obj != null) {
817 mContainerService = (IMediaContainerService) msg.obj;
819 if (mContainerService == null) {
820 // Something seriously wrong. Bail out
821 Slog.e(TAG, "Cannot bind to media container service");
822 for (HandlerParams params : mPendingInstalls) {
823 // Indicate service bind error
824 params.serviceError();
826 mPendingInstalls.clear();
827 } else if (mPendingInstalls.size() > 0) {
828 HandlerParams params = mPendingInstalls.get(0);
829 if (params != null) {
830 if (params.startCopy()) {
831 // We are done... look for more work or to
833 if (DEBUG_SD_INSTALL) Log.i(TAG,
834 "Checking for more work or unbind...");
835 // Delete pending install
836 if (mPendingInstalls.size() > 0) {
837 mPendingInstalls.remove(0);
839 if (mPendingInstalls.size() == 0) {
841 if (DEBUG_SD_INSTALL) Log.i(TAG,
842 "Posting delayed MCS_UNBIND");
843 removeMessages(MCS_UNBIND);
844 Message ubmsg = obtainMessage(MCS_UNBIND);
845 // Unbind after a little delay, to avoid
846 // continual thrashing.
847 sendMessageDelayed(ubmsg, 10000);
850 // There are more pending requests in queue.
851 // Just post MCS_BOUND message to trigger processing
852 // of next pending install.
853 if (DEBUG_SD_INSTALL) Log.i(TAG,
854 "Posting MCS_BOUND for next work");
855 mHandler.sendEmptyMessage(MCS_BOUND);
860 // Should never happen ideally.
861 Slog.w(TAG, "Empty queue");
865 case MCS_RECONNECT: {
866 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
867 if (mPendingInstalls.size() > 0) {
871 if (!connectToService()) {
872 Slog.e(TAG, "Failed to bind to media container service");
873 for (HandlerParams params : mPendingInstalls) {
874 // Indicate service bind error
875 params.serviceError();
877 mPendingInstalls.clear();
883 // If there is no actual work left, then time to unbind.
884 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
886 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
888 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
892 } else if (mPendingInstalls.size() > 0) {
893 // There are more pending requests in queue.
894 // Just post MCS_BOUND message to trigger processing
895 // of next pending install.
896 mHandler.sendEmptyMessage(MCS_BOUND);
902 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
903 mPendingInstalls.remove(0);
906 case SEND_PENDING_BROADCAST: {
908 ArrayList<String> components[];
911 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
912 synchronized (mPackages) {
913 if (mPendingBroadcasts == null) {
916 size = mPendingBroadcasts.size();
918 // Nothing to be done. Just return
921 packages = new String[size];
922 components = new ArrayList[size];
923 uids = new int[size];
924 int i = 0; // filling out the above arrays
926 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
927 int packageUserId = mPendingBroadcasts.userIdAt(n);
928 Iterator<Map.Entry<String, ArrayList<String>>> it
929 = mPendingBroadcasts.packagesForUserId(packageUserId)
930 .entrySet().iterator();
931 while (it.hasNext() && i < size) {
932 Map.Entry<String, ArrayList<String>> ent = it.next();
933 packages[i] = ent.getKey();
934 components[i] = ent.getValue();
935 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
936 uids[i] = (ps != null)
937 ? UserHandle.getUid(packageUserId, ps.appId)
943 mPendingBroadcasts.clear();
946 for (int i = 0; i < size; i++) {
947 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
949 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
952 case START_CLEANING_PACKAGE: {
953 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
954 final String packageName = (String)msg.obj;
955 final int userId = msg.arg1;
956 final boolean andCode = msg.arg2 != 0;
957 synchronized (mPackages) {
958 if (userId == UserHandle.USER_ALL) {
959 int[] users = sUserManager.getUserIds();
960 for (int user : users) {
961 mSettings.addPackageToCleanLPw(
962 new PackageCleanItem(user, packageName, andCode));
965 mSettings.addPackageToCleanLPw(
966 new PackageCleanItem(userId, packageName, andCode));
969 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
970 startCleaningPackages();
973 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
974 PostInstallData data = mRunningInstalls.get(msg.arg1);
975 mRunningInstalls.delete(msg.arg1);
976 boolean deleteOld = false;
979 InstallArgs args = data.args;
980 PackageInstalledInfo res = data.res;
982 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
983 res.removedInfo.sendBroadcast(false, true, false);
984 Bundle extras = new Bundle(1);
985 extras.putInt(Intent.EXTRA_UID, res.uid);
986 // Determine the set of users who are adding this
987 // package for the first time vs. those who are seeing
990 int[] updateUsers = new int[0];
991 if (res.origUsers == null || res.origUsers.length == 0) {
992 firstUsers = res.newUsers;
994 firstUsers = new int[0];
995 for (int i=0; i<res.newUsers.length; i++) {
996 int user = res.newUsers[i];
997 boolean isNew = true;
998 for (int j=0; j<res.origUsers.length; j++) {
999 if (res.origUsers[j] == user) {
1005 int[] newFirst = new int[firstUsers.length+1];
1006 System.arraycopy(firstUsers, 0, newFirst, 0,
1008 newFirst[firstUsers.length] = user;
1009 firstUsers = newFirst;
1011 int[] newUpdate = new int[updateUsers.length+1];
1012 System.arraycopy(updateUsers, 0, newUpdate, 0,
1013 updateUsers.length);
1014 newUpdate[updateUsers.length] = user;
1015 updateUsers = newUpdate;
1019 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1020 res.pkg.applicationInfo.packageName,
1021 extras, null, null, firstUsers);
1022 final boolean update = res.removedInfo.removedPackage != null;
1024 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1026 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1027 res.pkg.applicationInfo.packageName,
1028 extras, null, null, updateUsers);
1030 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1031 res.pkg.applicationInfo.packageName,
1032 extras, null, null, updateUsers);
1033 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1035 res.pkg.applicationInfo.packageName, null, updateUsers);
1037 // treat asec-hosted packages like removable media on upgrade
1038 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
1039 if (DEBUG_INSTALL) {
1040 Slog.i(TAG, "upgrading pkg " + res.pkg
1041 + " is ASEC-hosted -> AVAILABLE");
1043 int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1044 ArrayList<String> pkgList = new ArrayList<String>(1);
1045 pkgList.add(res.pkg.applicationInfo.packageName);
1046 sendResourcesChangedBroadcast(true, true,
1047 pkgList,uidArray, null);
1050 if (res.removedInfo.args != null) {
1051 // Remove the replaced package's older resources safely now
1055 // Log current value of "unknown sources" setting
1056 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1057 getUnknownSourcesSettings());
1059 // Force a gc to clear up things
1060 Runtime.getRuntime().gc();
1061 // We delete after a gc for applications on sdcard.
1063 synchronized (mInstallLock) {
1064 res.removedInfo.args.doPostDeleteLI(true);
1067 if (args.observer != null) {
1069 Bundle extras = extrasForInstallResult(res);
1070 args.observer.onPackageInstalled(res.name, res.returnCode,
1071 res.returnMsg, extras);
1072 } catch (RemoteException e) {
1073 Slog.i(TAG, "Observer no longer exists.");
1077 Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1080 case UPDATED_MEDIA_STATUS: {
1081 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1082 boolean reportStatus = msg.arg1 == 1;
1083 boolean doGc = msg.arg2 == 1;
1084 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1086 // Force a gc to clear up stale containers.
1087 Runtime.getRuntime().gc();
1089 if (msg.obj != null) {
1090 @SuppressWarnings("unchecked")
1091 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1092 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1093 // Unload containers
1094 unloadAllContainers(args);
1098 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1099 PackageHelper.getMountService().finishMediaUpdate();
1100 } catch (RemoteException e) {
1101 Log.e(TAG, "MountService not running?");
1105 case WRITE_SETTINGS: {
1106 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1107 synchronized (mPackages) {
1108 removeMessages(WRITE_SETTINGS);
1109 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1110 mSettings.writeLPr();
1111 mDirtyUsers.clear();
1113 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1115 case WRITE_PACKAGE_RESTRICTIONS: {
1116 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1117 synchronized (mPackages) {
1118 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1119 for (int userId : mDirtyUsers) {
1120 mSettings.writePackageRestrictionsLPr(userId);
1122 mDirtyUsers.clear();
1124 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1126 case CHECK_PENDING_VERIFICATION: {
1127 final int verificationId = msg.arg1;
1128 final PackageVerificationState state = mPendingVerification.get(verificationId);
1130 if ((state != null) && !state.timeoutExtended()) {
1131 final InstallArgs args = state.getInstallArgs();
1132 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1134 Slog.i(TAG, "Verification timed out for " + originUri);
1135 mPendingVerification.remove(verificationId);
1137 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1139 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1140 Slog.i(TAG, "Continuing with installation of " + originUri);
1141 state.setVerifierResponse(Binder.getCallingUid(),
1142 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1143 broadcastPackageVerified(verificationId, originUri,
1144 PackageManager.VERIFICATION_ALLOW,
1145 state.getInstallArgs().getUser());
1147 ret = args.copyApk(mContainerService, true);
1148 } catch (RemoteException e) {
1149 Slog.e(TAG, "Could not contact the ContainerService");
1152 broadcastPackageVerified(verificationId, originUri,
1153 PackageManager.VERIFICATION_REJECT,
1154 state.getInstallArgs().getUser());
1157 processPendingInstall(args, ret);
1158 mHandler.sendEmptyMessage(MCS_UNBIND);
1162 case PACKAGE_VERIFIED: {
1163 final int verificationId = msg.arg1;
1165 final PackageVerificationState state = mPendingVerification.get(verificationId);
1166 if (state == null) {
1167 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1171 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1173 state.setVerifierResponse(response.callerUid, response.code);
1175 if (state.isVerificationComplete()) {
1176 mPendingVerification.remove(verificationId);
1178 final InstallArgs args = state.getInstallArgs();
1179 final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1182 if (state.isInstallAllowed()) {
1183 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1184 broadcastPackageVerified(verificationId, originUri,
1185 response.code, state.getInstallArgs().getUser());
1187 ret = args.copyApk(mContainerService, true);
1188 } catch (RemoteException e) {
1189 Slog.e(TAG, "Could not contact the ContainerService");
1192 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1195 processPendingInstall(args, ret);
1197 mHandler.sendEmptyMessage(MCS_UNBIND);
1206 Bundle extrasForInstallResult(PackageInstalledInfo res) {
1207 Bundle extras = null;
1208 switch (res.returnCode) {
1209 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1210 extras = new Bundle();
1211 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1212 res.origPermission);
1213 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1221 void scheduleWriteSettingsLocked() {
1222 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1223 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1227 void scheduleWritePackageRestrictionsLocked(int userId) {
1228 if (!sUserManager.exists(userId)) return;
1229 mDirtyUsers.add(userId);
1230 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1231 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1235 public static final PackageManagerService main(Context context, Installer installer,
1236 boolean factoryTest, boolean onlyCore) {
1237 PackageManagerService m = new PackageManagerService(context, installer,
1238 factoryTest, onlyCore);
1239 ServiceManager.addService("package", m);
1243 static String[] splitString(String str, char sep) {
1246 while ((i=str.indexOf(sep, i)) >= 0) {
1251 String[] res = new String[count];
1255 while ((i=str.indexOf(sep, i)) >= 0) {
1256 res[count] = str.substring(lastI, i);
1261 res[count] = str.substring(lastI, str.length());
1265 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1266 DisplayManager displayManager = (DisplayManager) context.getSystemService(
1267 Context.DISPLAY_SERVICE);
1268 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1271 public PackageManagerService(Context context, Installer installer,
1272 boolean factoryTest, boolean onlyCore) {
1273 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1274 SystemClock.uptimeMillis());
1276 if (mSdkVersion <= 0) {
1277 Slog.w(TAG, "**** ro.build.version.sdk not set!");
1281 mFactoryTest = factoryTest;
1282 mOnlyCore = onlyCore;
1283 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1284 mMetrics = new DisplayMetrics();
1285 mSettings = new Settings(context);
1286 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1287 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1288 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1289 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1290 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1291 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1292 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1293 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1294 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1295 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1296 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1297 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1299 // TODO: add a property to control this?
1300 long dexOptLRUThresholdInMinutes;
1302 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
1304 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
1306 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
1308 String separateProcesses = SystemProperties.get("debug.separate_processes");
1309 if (separateProcesses != null && separateProcesses.length() > 0) {
1310 if ("*".equals(separateProcesses)) {
1311 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1312 mSeparateProcesses = null;
1313 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1316 mSeparateProcesses = separateProcesses.split(",");
1317 Slog.w(TAG, "Running with debug.separate_processes: "
1318 + separateProcesses);
1322 mSeparateProcesses = null;
1325 mInstaller = installer;
1327 getDefaultDisplayMetrics(context, mMetrics);
1329 SystemConfig systemConfig = SystemConfig.getInstance();
1330 mGlobalGids = systemConfig.getGlobalGids();
1331 mSystemPermissions = systemConfig.getSystemPermissions();
1332 mAvailableFeatures = systemConfig.getAvailableFeatures();
1334 synchronized (mInstallLock) {
1336 synchronized (mPackages) {
1337 mHandlerThread = new ServiceThread(TAG,
1338 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1339 mHandlerThread.start();
1340 mHandler = new PackageHandler(mHandlerThread.getLooper());
1341 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1343 File dataDir = Environment.getDataDirectory();
1344 mAppDataDir = new File(dataDir, "data");
1345 mAppInstallDir = new File(dataDir, "app");
1346 mAppLib32InstallDir = new File(dataDir, "app-lib");
1347 mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1348 mUserAppDataDir = new File(dataDir, "user");
1349 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1351 sUserManager = new UserManagerService(context, this,
1352 mInstallLock, mPackages);
1354 // Propagate permission configuration in to package manager.
1355 ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1356 = systemConfig.getPermissions();
1357 for (int i=0; i<permConfig.size(); i++) {
1358 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1359 BasePermission bp = mSettings.mPermissions.get(perm.name);
1361 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1362 mSettings.mPermissions.put(perm.name, bp);
1364 if (perm.gids != null) {
1365 bp.gids = appendInts(bp.gids, perm.gids);
1369 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1370 for (int i=0; i<libConfig.size(); i++) {
1371 mSharedLibraries.put(libConfig.keyAt(i),
1372 new SharedLibraryEntry(libConfig.valueAt(i), null));
1375 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1377 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1378 mSdkVersion, mOnlyCore);
1380 String customResolverActivity = Resources.getSystem().getString(
1381 R.string.config_customResolverActivity);
1382 if (TextUtils.isEmpty(customResolverActivity)) {
1383 customResolverActivity = null;
1385 mCustomResolverComponentName = ComponentName.unflattenFromString(
1386 customResolverActivity);
1389 long startTime = SystemClock.uptimeMillis();
1391 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1394 // Set flag to monitor and not change apk file paths when
1395 // scanning install directories.
1396 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1398 final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
1401 * Add everything in the in the boot class path to the
1402 * list of process files because dexopt will have been run
1403 * if necessary during zygote startup.
1405 final String bootClassPath = System.getenv("BOOTCLASSPATH");
1406 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1408 if (bootClassPath != null) {
1409 String[] bootClassPathElements = splitString(bootClassPath, ':');
1410 for (String element : bootClassPathElements) {
1411 alreadyDexOpted.add(element);
1414 Slog.w(TAG, "No BOOTCLASSPATH found!");
1417 if (systemServerClassPath != null) {
1418 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1419 for (String element : systemServerClassPathElements) {
1420 alreadyDexOpted.add(element);
1423 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1426 final List<String> allInstructionSets = getAllInstructionSets();
1427 final String[] dexCodeInstructionSets =
1428 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
1431 * Ensure all external libraries have had dexopt run on them.
1433 if (mSharedLibraries.size() > 0) {
1434 // NOTE: For now, we're compiling these system "shared libraries"
1435 // (and framework jars) into all available architectures. It's possible
1436 // to compile them only when we come across an app that uses them (there's
1437 // already logic for that in scanPackageLI) but that adds some complexity.
1438 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1439 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1440 final String lib = libEntry.path;
1446 byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
1447 dexCodeInstructionSet,
1449 if (dexoptRequired != DexFile.UP_TO_DATE) {
1450 alreadyDexOpted.add(lib);
1452 // The list of "shared libraries" we have at this point is
1453 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1454 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1456 mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1459 } catch (FileNotFoundException e) {
1460 Slog.w(TAG, "Library not found: " + lib);
1461 } catch (IOException e) {
1462 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1469 File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1471 // Gross hack for now: we know this file doesn't contain any
1472 // code, so don't dexopt it to avoid the resulting log spew.
1473 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1475 // Gross hack for now: we know this file is only part of
1476 // the boot class path for art, so don't dexopt it to
1477 // avoid the resulting log spew.
1478 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1481 * And there are a number of commands implemented in Java, which
1482 * we currently need to do the dexopt on so that they can be
1483 * run from a non-root shell.
1485 String[] frameworkFiles = frameworkDir.list();
1486 if (frameworkFiles != null) {
1487 // TODO: We could compile these only for the most preferred ABI. We should
1488 // first double check that the dex files for these commands are not referenced
1489 // by other system apps.
1490 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1491 for (int i=0; i<frameworkFiles.length; i++) {
1492 File libPath = new File(frameworkDir, frameworkFiles[i]);
1493 String path = libPath.getPath();
1494 // Skip the file if we already did it.
1495 if (alreadyDexOpted.contains(path)) {
1498 // Skip the file if it is not a type we want to dexopt.
1499 if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1503 byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
1504 dexCodeInstructionSet,
1506 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1507 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1508 } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
1509 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1511 } catch (FileNotFoundException e) {
1512 Slog.w(TAG, "Jar not found: " + path);
1513 } catch (IOException e) {
1514 Slog.w(TAG, "Exception reading jar: " + path, e);
1520 // Collect vendor overlay packages.
1521 // (Do this before scanning any apps.)
1522 // For security and version matching reason, only consider
1523 // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1524 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1525 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1526 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
1528 // Find base frameworks (resource packages without code).
1529 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1530 | PackageParser.PARSE_IS_SYSTEM_DIR
1531 | PackageParser.PARSE_IS_PRIVILEGED,
1532 scanFlags | SCAN_NO_DEX, 0);
1534 // Collected privileged system packages.
1535 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1536 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1537 | PackageParser.PARSE_IS_SYSTEM_DIR
1538 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
1540 // Collect ordinary system packages.
1541 final File systemAppDir = new File(Environment.getRootDirectory(), "app");
1542 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1543 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1545 // Collect all vendor packages.
1546 File vendorAppDir = new File("/vendor/app");
1548 vendorAppDir = vendorAppDir.getCanonicalFile();
1549 } catch (IOException e) {
1550 // failed to look up canonical path, continue with original one
1552 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1553 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1555 // Collect all OEM packages.
1556 final File oemAppDir = new File(Environment.getOemDirectory(), "app");
1557 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1558 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1560 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1561 mInstaller.moveFiles();
1563 // Prune any system packages that no longer exist.
1564 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1565 final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
1567 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1568 while (psit.hasNext()) {
1569 PackageSetting ps = psit.next();
1572 * If this is not a system app, it can't be a
1573 * disable system app.
1575 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1580 * If the package is scanned, it's not erased.
1582 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1583 if (scannedPkg != null) {
1585 * If the system app is both scanned and in the
1586 * disabled packages list, then it must have been
1587 * added via OTA. Remove it from the currently
1588 * scanned package so the previously user-installed
1589 * application can be scanned.
1591 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1592 logCriticalInfo(Log.WARN, "Expecting better updated system app for "
1593 + ps.name + "; removing system app. Last known codePath="
1594 + ps.codePathString + ", installStatus=" + ps.installStatus
1595 + ", versionCode=" + ps.versionCode + "; scanned versionCode="
1596 + scannedPkg.mVersionCode);
1597 removePackageLI(ps, true);
1598 expectingBetter.put(ps.name, ps.codePath);
1604 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1606 logCriticalInfo(Log.WARN, "System package " + ps.name
1607 + " no longer exists; wiping its data");
1608 removeDataDirsLI(ps.name);
1610 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1611 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1612 possiblyDeletedUpdatedSystemApps.add(ps.name);
1618 //look for any incomplete package installations
1619 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1621 for(int i = 0; i < deletePkgsList.size(); i++) {
1623 cleanupInstallFailedPackage(deletePkgsList.get(i));
1626 deleteTempPackageFiles();
1628 // Remove any shared userIDs that have no associated packages
1629 mSettings.pruneSharedUsersLPw();
1632 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1633 SystemClock.uptimeMillis());
1634 scanDirLI(mAppInstallDir, 0, scanFlags, 0);
1636 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1640 * Remove disable package settings for any updated system
1641 * apps that were removed via an OTA. If they're not a
1642 * previously-updated app, remove them completely.
1643 * Otherwise, just revoke their system-level permissions.
1645 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1646 PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1647 mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1650 if (deletedPkg == null) {
1651 msg = "Updated system package " + deletedAppName
1652 + " no longer exists; wiping its data";
1653 removeDataDirsLI(deletedAppName);
1655 msg = "Updated system app + " + deletedAppName
1656 + " no longer present; removing system privileges for "
1659 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1661 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1662 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1664 logCriticalInfo(Log.WARN, msg);
1668 * Make sure all system apps that we expected to appear on
1669 * the userdata partition actually showed up. If they never
1670 * appeared, crawl back and revive the system version.
1672 for (int i = 0; i < expectingBetter.size(); i++) {
1673 final String packageName = expectingBetter.keyAt(i);
1674 if (!mPackages.containsKey(packageName)) {
1675 final File scanFile = expectingBetter.valueAt(i);
1677 logCriticalInfo(Log.WARN, "Expected better " + packageName
1678 + " but never showed up; reverting to system");
1680 final int reparseFlags;
1681 if (FileUtils.contains(privilegedAppDir, scanFile)) {
1682 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1683 | PackageParser.PARSE_IS_SYSTEM_DIR
1684 | PackageParser.PARSE_IS_PRIVILEGED;
1685 } else if (FileUtils.contains(systemAppDir, scanFile)) {
1686 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1687 | PackageParser.PARSE_IS_SYSTEM_DIR;
1688 } else if (FileUtils.contains(vendorAppDir, scanFile)) {
1689 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1690 | PackageParser.PARSE_IS_SYSTEM_DIR;
1691 } else if (FileUtils.contains(oemAppDir, scanFile)) {
1692 reparseFlags = PackageParser.PARSE_IS_SYSTEM
1693 | PackageParser.PARSE_IS_SYSTEM_DIR;
1695 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
1699 mSettings.enableSystemPackageLPw(packageName);
1702 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
1703 } catch (PackageManagerException e) {
1704 Slog.e(TAG, "Failed to parse original system package: "
1711 // Now that we know all of the shared libraries, update all clients to have
1712 // the correct library paths.
1713 updateAllSharedLibrariesLPw();
1715 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
1716 // NOTE: We ignore potential failures here during a system scan (like
1717 // the rest of the commands above) because there's precious little we
1718 // can do about it. A settings error is reported, though.
1719 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
1720 false /* force dexopt */, false /* defer dexopt */);
1723 // Now that we know all the packages we are keeping,
1724 // read and update their last usage times.
1725 mPackageUsage.readLP();
1727 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1728 SystemClock.uptimeMillis());
1729 Slog.i(TAG, "Time to scan packages: "
1730 + ((SystemClock.uptimeMillis()-startTime)/1000f)
1733 // If the platform SDK has changed since the last time we booted,
1734 // we need to re-grant app permission to catch any new ones that
1735 // appear. This is really a hack, and means that apps can in some
1736 // cases get permissions that the user didn't initially explicitly
1737 // allow... it would be nice to have some better way to handle
1739 final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1741 if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1742 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1743 + "; regranting permissions for internal storage");
1744 mSettings.mInternalSdkPlatform = mSdkVersion;
1746 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1747 | (regrantPermissions
1748 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1751 // If this is the first boot, and it is a normal boot, then
1752 // we need to initialize the default preferred apps.
1753 if (!mRestoredSettings && !onlyCore) {
1754 mSettings.readDefaultPreferredAppsLPw(this, 0);
1757 // If this is first boot after an OTA, and a normal boot, then
1758 // we need to clear code cache directories.
1759 mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
1760 if (mIsUpgrade && !onlyCore) {
1761 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
1762 for (String pkgName : mSettings.mPackages.keySet()) {
1763 deleteCodeCacheDirsLI(pkgName);
1765 mSettings.mFingerprint = Build.FINGERPRINT;
1768 // All the changes are done during package scanning.
1769 mSettings.updateInternalDatabaseVersion();
1771 // can downgrade to reader
1772 mSettings.writeLPr();
1774 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1775 SystemClock.uptimeMillis());
1778 mRequiredVerifierPackage = getRequiredVerifierLPr();
1779 } // synchronized (mPackages)
1780 } // synchronized (mInstallLock)
1782 mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
1784 // Now after opening every single application zip, make sure they
1785 // are all flushed. Not really needed, but keeps things nice and
1787 Runtime.getRuntime().gc();
1791 public boolean isFirstBoot() {
1792 return !mRestoredSettings;
1796 public boolean isOnlyCoreApps() {
1801 public boolean isUpgrade() {
1805 private String getRequiredVerifierLPr() {
1806 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1807 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1808 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1810 String requiredVerifier = null;
1812 final int N = receivers.size();
1813 for (int i = 0; i < N; i++) {
1814 final ResolveInfo info = receivers.get(i);
1816 if (info.activityInfo == null) {
1820 final String packageName = info.activityInfo.packageName;
1822 final PackageSetting ps = mSettings.mPackages.get(packageName);
1827 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1828 if (!gp.grantedPermissions
1829 .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1833 if (requiredVerifier != null) {
1834 throw new RuntimeException("There can be only one required verifier");
1837 requiredVerifier = packageName;
1840 return requiredVerifier;
1844 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1845 throws RemoteException {
1847 return super.onTransact(code, data, reply, flags);
1848 } catch (RuntimeException e) {
1849 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1850 Slog.wtf(TAG, "Package Manager Crash", e);
1856 void cleanupInstallFailedPackage(PackageSetting ps) {
1857 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
1859 removeDataDirsLI(ps.name);
1860 if (ps.codePath != null) {
1861 if (ps.codePath.isDirectory()) {
1862 FileUtils.deleteContents(ps.codePath);
1864 ps.codePath.delete();
1866 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
1867 if (ps.resourcePath.isDirectory()) {
1868 FileUtils.deleteContents(ps.resourcePath);
1870 ps.resourcePath.delete();
1872 mSettings.removePackageLPw(ps.name);
1875 static int[] appendInts(int[] cur, int[] add) {
1876 if (add == null) return cur;
1877 if (cur == null) return add;
1878 final int N = add.length;
1879 for (int i=0; i<N; i++) {
1880 cur = appendInt(cur, add[i]);
1885 static int[] removeInts(int[] cur, int[] rem) {
1886 if (rem == null) return cur;
1887 if (cur == null) return cur;
1888 final int N = rem.length;
1889 for (int i=0; i<N; i++) {
1890 cur = removeInt(cur, rem[i]);
1895 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1896 if (!sUserManager.exists(userId)) return null;
1897 final PackageSetting ps = (PackageSetting) p.mExtras;
1901 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1902 final PackageUserState state = ps.readUserState(userId);
1903 return PackageParser.generatePackageInfo(p, gp.gids, flags,
1904 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1909 public boolean isPackageAvailable(String packageName, int userId) {
1910 if (!sUserManager.exists(userId)) return false;
1911 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
1912 synchronized (mPackages) {
1913 PackageParser.Package p = mPackages.get(packageName);
1915 final PackageSetting ps = (PackageSetting) p.mExtras;
1917 final PackageUserState state = ps.readUserState(userId);
1918 if (state != null) {
1919 return PackageParser.isAvailable(state);
1928 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1929 if (!sUserManager.exists(userId)) return null;
1930 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
1932 synchronized (mPackages) {
1933 PackageParser.Package p = mPackages.get(packageName);
1934 if (DEBUG_PACKAGE_INFO)
1935 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1937 return generatePackageInfo(p, flags, userId);
1939 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1940 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1947 public String[] currentToCanonicalPackageNames(String[] names) {
1948 String[] out = new String[names.length];
1950 synchronized (mPackages) {
1951 for (int i=names.length-1; i>=0; i--) {
1952 PackageSetting ps = mSettings.mPackages.get(names[i]);
1953 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1960 public String[] canonicalToCurrentPackageNames(String[] names) {
1961 String[] out = new String[names.length];
1963 synchronized (mPackages) {
1964 for (int i=names.length-1; i>=0; i--) {
1965 String cur = mSettings.mRenamedPackages.get(names[i]);
1966 out[i] = cur != null ? cur : names[i];
1973 public int getPackageUid(String packageName, int userId) {
1974 if (!sUserManager.exists(userId)) return -1;
1975 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
1977 synchronized (mPackages) {
1978 PackageParser.Package p = mPackages.get(packageName);
1980 return UserHandle.getUid(userId, p.applicationInfo.uid);
1982 PackageSetting ps = mSettings.mPackages.get(packageName);
1983 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1987 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1992 public int[] getPackageGids(String packageName) {
1994 synchronized (mPackages) {
1995 PackageParser.Package p = mPackages.get(packageName);
1996 if (DEBUG_PACKAGE_INFO)
1997 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1999 final PackageSetting ps = (PackageSetting)p.mExtras;
2000 return ps.getGids();
2003 // stupid thing to indicate an error.
2007 static final PermissionInfo generatePermissionInfo(
2008 BasePermission bp, int flags) {
2009 if (bp.perm != null) {
2010 return PackageParser.generatePermissionInfo(bp.perm, flags);
2012 PermissionInfo pi = new PermissionInfo();
2014 pi.packageName = bp.sourcePackage;
2015 pi.nonLocalizedLabel = bp.name;
2016 pi.protectionLevel = bp.protectionLevel;
2021 public PermissionInfo getPermissionInfo(String name, int flags) {
2023 synchronized (mPackages) {
2024 final BasePermission p = mSettings.mPermissions.get(name);
2026 return generatePermissionInfo(p, flags);
2033 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2035 synchronized (mPackages) {
2036 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2037 for (BasePermission p : mSettings.mPermissions.values()) {
2038 if (group == null) {
2039 if (p.perm == null || p.perm.info.group == null) {
2040 out.add(generatePermissionInfo(p, flags));
2043 if (p.perm != null && group.equals(p.perm.info.group)) {
2044 out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2049 if (out.size() > 0) {
2052 return mPermissionGroups.containsKey(group) ? out : null;
2057 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2059 synchronized (mPackages) {
2060 return PackageParser.generatePermissionGroupInfo(
2061 mPermissionGroups.get(name), flags);
2066 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2068 synchronized (mPackages) {
2069 final int N = mPermissionGroups.size();
2070 ArrayList<PermissionGroupInfo> out
2071 = new ArrayList<PermissionGroupInfo>(N);
2072 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2073 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2079 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2081 if (!sUserManager.exists(userId)) return null;
2082 PackageSetting ps = mSettings.mPackages.get(packageName);
2084 if (ps.pkg == null) {
2085 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2087 if (pInfo != null) {
2088 return pInfo.applicationInfo;
2092 return PackageParser.generateApplicationInfo(ps.pkg, flags,
2093 ps.readUserState(userId), userId);
2098 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2100 if (!sUserManager.exists(userId)) return null;
2101 PackageSetting ps = mSettings.mPackages.get(packageName);
2103 PackageParser.Package pkg = ps.pkg;
2105 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2108 // Only data remains, so we aren't worried about code paths
2109 pkg = new PackageParser.Package(packageName);
2110 pkg.applicationInfo.packageName = packageName;
2111 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2112 pkg.applicationInfo.dataDir =
2113 getDataPathForPackage(packageName, 0).getPath();
2114 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2115 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2117 return generatePackageInfo(pkg, flags, userId);
2123 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2124 if (!sUserManager.exists(userId)) return null;
2125 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2127 synchronized (mPackages) {
2128 PackageParser.Package p = mPackages.get(packageName);
2129 if (DEBUG_PACKAGE_INFO) Log.v(
2130 TAG, "getApplicationInfo " + packageName
2133 PackageSetting ps = mSettings.mPackages.get(packageName);
2134 if (ps == null) return null;
2135 // Note: isEnabledLP() does not apply here - always return info
2136 return PackageParser.generateApplicationInfo(
2137 p, flags, ps.readUserState(userId), userId);
2139 if ("android".equals(packageName)||"system".equals(packageName)) {
2140 return mAndroidApplication;
2142 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2143 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2151 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
2152 mContext.enforceCallingOrSelfPermission(
2153 android.Manifest.permission.CLEAR_APP_CACHE, null);
2154 // Queue up an async operation since clearing cache may take a little while.
2155 mHandler.post(new Runnable() {
2157 mHandler.removeCallbacks(this);
2159 synchronized (mInstallLock) {
2160 retCode = mInstaller.freeCache(freeStorageSize);
2162 Slog.w(TAG, "Couldn't clear application caches");
2165 if (observer != null) {
2167 observer.onRemoveCompleted(null, (retCode >= 0));
2168 } catch (RemoteException e) {
2169 Slog.w(TAG, "RemoveException when invoking call back");
2177 public void freeStorage(final long freeStorageSize, final IntentSender pi) {
2178 mContext.enforceCallingOrSelfPermission(
2179 android.Manifest.permission.CLEAR_APP_CACHE, null);
2180 // Queue up an async operation since clearing cache may take a little while.
2181 mHandler.post(new Runnable() {
2183 mHandler.removeCallbacks(this);
2185 synchronized (mInstallLock) {
2186 retCode = mInstaller.freeCache(freeStorageSize);
2188 Slog.w(TAG, "Couldn't clear application caches");
2193 // Callback via pending intent
2194 int code = (retCode >= 0) ? 1 : 0;
2195 pi.sendIntent(null, code, null,
2197 } catch (SendIntentException e1) {
2198 Slog.i(TAG, "Failed to send pending intent");
2205 void freeStorage(long freeStorageSize) throws IOException {
2206 synchronized (mInstallLock) {
2207 if (mInstaller.freeCache(freeStorageSize) < 0) {
2208 throw new IOException("Failed to free enough space");
2214 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2215 if (!sUserManager.exists(userId)) return null;
2216 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
2217 synchronized (mPackages) {
2218 PackageParser.Activity a = mActivities.mActivities.get(component);
2220 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2221 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2222 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2223 if (ps == null) return null;
2224 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2227 if (mResolveComponentName.equals(component)) {
2228 return PackageParser.generateActivityInfo(mResolveActivity, flags,
2229 new PackageUserState(), userId);
2236 public boolean activitySupportsIntent(ComponentName component, Intent intent,
2237 String resolvedType) {
2238 synchronized (mPackages) {
2239 PackageParser.Activity a = mActivities.mActivities.get(component);
2243 for (int i=0; i<a.intents.size(); i++) {
2244 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2245 intent.getData(), intent.getCategories(), TAG) >= 0) {
2254 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2255 if (!sUserManager.exists(userId)) return null;
2256 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
2257 synchronized (mPackages) {
2258 PackageParser.Activity a = mReceivers.mActivities.get(component);
2259 if (DEBUG_PACKAGE_INFO) Log.v(
2260 TAG, "getReceiverInfo " + component + ": " + a);
2261 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2262 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2263 if (ps == null) return null;
2264 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2272 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2273 if (!sUserManager.exists(userId)) return null;
2274 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
2275 synchronized (mPackages) {
2276 PackageParser.Service s = mServices.mServices.get(component);
2277 if (DEBUG_PACKAGE_INFO) Log.v(
2278 TAG, "getServiceInfo " + component + ": " + s);
2279 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2280 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2281 if (ps == null) return null;
2282 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2290 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2291 if (!sUserManager.exists(userId)) return null;
2292 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
2293 synchronized (mPackages) {
2294 PackageParser.Provider p = mProviders.mProviders.get(component);
2295 if (DEBUG_PACKAGE_INFO) Log.v(
2296 TAG, "getProviderInfo " + component + ": " + p);
2297 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2298 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2299 if (ps == null) return null;
2300 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2308 public String[] getSystemSharedLibraryNames() {
2310 synchronized (mPackages) {
2311 libSet = mSharedLibraries.keySet();
2312 int size = libSet.size();
2314 String[] libs = new String[size];
2315 libSet.toArray(libs);
2323 public FeatureInfo[] getSystemAvailableFeatures() {
2324 Collection<FeatureInfo> featSet;
2325 synchronized (mPackages) {
2326 featSet = mAvailableFeatures.values();
2327 int size = featSet.size();
2329 FeatureInfo[] features = new FeatureInfo[size+1];
2330 featSet.toArray(features);
2331 FeatureInfo fi = new FeatureInfo();
2332 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2333 FeatureInfo.GL_ES_VERSION_UNDEFINED);
2334 features[size] = fi;
2342 public boolean hasSystemFeature(String name) {
2343 synchronized (mPackages) {
2344 return mAvailableFeatures.containsKey(name);
2348 private void checkValidCaller(int uid, int userId) {
2349 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2352 throw new SecurityException("Caller uid=" + uid
2353 + " is not privileged to communicate with user=" + userId);
2357 public int checkPermission(String permName, String pkgName) {
2358 synchronized (mPackages) {
2359 PackageParser.Package p = mPackages.get(pkgName);
2360 if (p != null && p.mExtras != null) {
2361 PackageSetting ps = (PackageSetting)p.mExtras;
2362 if (ps.sharedUser != null) {
2363 if (ps.sharedUser.grantedPermissions.contains(permName)) {
2364 return PackageManager.PERMISSION_GRANTED;
2366 } else if (ps.grantedPermissions.contains(permName)) {
2367 return PackageManager.PERMISSION_GRANTED;
2371 return PackageManager.PERMISSION_DENIED;
2375 public int checkUidPermission(String permName, int uid) {
2376 synchronized (mPackages) {
2377 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2379 GrantedPermissions gp = (GrantedPermissions)obj;
2380 if (gp.grantedPermissions.contains(permName)) {
2381 return PackageManager.PERMISSION_GRANTED;
2384 ArraySet<String> perms = mSystemPermissions.get(uid);
2385 if (perms != null && perms.contains(permName)) {
2386 return PackageManager.PERMISSION_GRANTED;
2390 return PackageManager.PERMISSION_DENIED;
2394 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2395 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2396 * @param checkShell TODO(yamasani):
2397 * @param message the message to log on security exception
2399 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
2400 boolean checkShell, String message) {
2402 throw new IllegalArgumentException("Invalid userId " + userId);
2405 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2407 if (userId == UserHandle.getUserId(callingUid)) return;
2408 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2409 if (requireFullPermission) {
2410 mContext.enforceCallingOrSelfPermission(
2411 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2414 mContext.enforceCallingOrSelfPermission(
2415 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2416 } catch (SecurityException se) {
2417 mContext.enforceCallingOrSelfPermission(
2418 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2424 void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
2425 if (callingUid == Process.SHELL_UID) {
2427 && sUserManager.hasUserRestriction(restriction, userHandle)) {
2428 throw new SecurityException("Shell does not have permission to access user "
2430 } else if (userHandle < 0) {
2431 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
2432 + Debug.getCallers(3));
2437 private BasePermission findPermissionTreeLP(String permName) {
2438 for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2439 if (permName.startsWith(bp.name) &&
2440 permName.length() > bp.name.length() &&
2441 permName.charAt(bp.name.length()) == '.') {
2448 private BasePermission checkPermissionTreeLP(String permName) {
2449 if (permName != null) {
2450 BasePermission bp = findPermissionTreeLP(permName);
2452 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2455 throw new SecurityException("Calling uid "
2456 + Binder.getCallingUid()
2457 + " is not allowed to add to permission tree "
2458 + bp.name + " owned by uid " + bp.uid);
2461 throw new SecurityException("No permission tree found for " + permName);
2464 static boolean compareStrings(CharSequence s1, CharSequence s2) {
2471 if (s1.getClass() != s2.getClass()) {
2474 return s1.equals(s2);
2477 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2478 if (pi1.icon != pi2.icon) return false;
2479 if (pi1.logo != pi2.logo) return false;
2480 if (pi1.protectionLevel != pi2.protectionLevel) return false;
2481 if (!compareStrings(pi1.name, pi2.name)) return false;
2482 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2483 // We'll take care of setting this one.
2484 if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2485 // These are not currently stored in settings.
2486 //if (!compareStrings(pi1.group, pi2.group)) return false;
2487 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2488 //if (pi1.labelRes != pi2.labelRes) return false;
2489 //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2493 int permissionInfoFootprint(PermissionInfo info) {
2494 int size = info.name.length();
2495 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
2496 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
2500 int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2502 for (BasePermission perm : mSettings.mPermissions.values()) {
2503 if (perm.uid == tree.uid) {
2504 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
2510 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2511 // We calculate the max size of permissions defined by this uid and throw
2512 // if that plus the size of 'info' would exceed our stated maximum.
2513 if (tree.uid != Process.SYSTEM_UID) {
2514 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2515 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
2516 throw new SecurityException("Permission tree size cap exceeded");
2521 boolean addPermissionLocked(PermissionInfo info, boolean async) {
2522 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2523 throw new SecurityException("Label must be specified in permission");
2525 BasePermission tree = checkPermissionTreeLP(info.name);
2526 BasePermission bp = mSettings.mPermissions.get(info.name);
2527 boolean added = bp == null;
2528 boolean changed = true;
2529 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2531 enforcePermissionCapLocked(info, tree);
2532 bp = new BasePermission(info.name, tree.sourcePackage,
2533 BasePermission.TYPE_DYNAMIC);
2534 } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2535 throw new SecurityException(
2536 "Not allowed to modify non-dynamic permission "
2539 if (bp.protectionLevel == fixedLevel
2540 && bp.perm.owner.equals(tree.perm.owner)
2541 && bp.uid == tree.uid
2542 && comparePermissionInfos(bp.perm.info, info)) {
2546 bp.protectionLevel = fixedLevel;
2547 info = new PermissionInfo(info);
2548 info.protectionLevel = fixedLevel;
2549 bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2550 bp.perm.info.packageName = tree.perm.info.packageName;
2553 mSettings.mPermissions.put(info.name, bp);
2557 mSettings.writeLPr();
2559 scheduleWriteSettingsLocked();
2566 public boolean addPermission(PermissionInfo info) {
2567 synchronized (mPackages) {
2568 return addPermissionLocked(info, false);
2573 public boolean addPermissionAsync(PermissionInfo info) {
2574 synchronized (mPackages) {
2575 return addPermissionLocked(info, true);
2580 public void removePermission(String name) {
2581 synchronized (mPackages) {
2582 checkPermissionTreeLP(name);
2583 BasePermission bp = mSettings.mPermissions.get(name);
2585 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2586 throw new SecurityException(
2587 "Not allowed to modify non-dynamic permission "
2590 mSettings.mPermissions.remove(name);
2591 mSettings.writeLPr();
2596 private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2597 int index = pkg.requestedPermissions.indexOf(bp.name);
2599 throw new SecurityException("Package " + pkg.packageName
2600 + " has not requested permission " + bp.name);
2603 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2604 == PermissionInfo.PROTECTION_NORMAL);
2605 boolean isDangerous =
2606 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2607 == PermissionInfo.PROTECTION_DANGEROUS);
2608 boolean isDevelopment =
2609 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2611 if (!isNormal && !isDangerous && !isDevelopment) {
2612 throw new SecurityException("Permission " + bp.name
2613 + " is not a changeable permission type");
2616 if (isNormal || isDangerous) {
2617 if (pkg.requestedPermissionsRequired.get(index)) {
2618 throw new SecurityException("Can't change " + bp.name
2619 + ". It is required by the application");
2625 public void grantPermission(String packageName, String permissionName) {
2626 mContext.enforceCallingOrSelfPermission(
2627 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2628 synchronized (mPackages) {
2629 final PackageParser.Package pkg = mPackages.get(packageName);
2631 throw new IllegalArgumentException("Unknown package: " + packageName);
2633 final BasePermission bp = mSettings.mPermissions.get(permissionName);
2635 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2638 checkGrantRevokePermissions(pkg, bp);
2640 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2644 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2645 if (gp.grantedPermissions.add(permissionName)) {
2647 gp.gids = appendInts(gp.gids, bp.gids);
2649 mSettings.writeLPr();
2655 public void revokePermission(String packageName, String permissionName) {
2656 int changedAppId = -1;
2658 synchronized (mPackages) {
2659 final PackageParser.Package pkg = mPackages.get(packageName);
2661 throw new IllegalArgumentException("Unknown package: " + packageName);
2663 if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2664 mContext.enforceCallingOrSelfPermission(
2665 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2667 final BasePermission bp = mSettings.mPermissions.get(permissionName);
2669 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2672 checkGrantRevokePermissions(pkg, bp);
2674 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2678 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2679 if (gp.grantedPermissions.remove(permissionName)) {
2680 gp.grantedPermissions.remove(permissionName);
2682 gp.gids = removeInts(gp.gids, bp.gids);
2684 mSettings.writeLPr();
2685 changedAppId = ps.appId;
2689 if (changedAppId >= 0) {
2690 // We changed the perm on someone, kill its processes.
2691 IActivityManager am = ActivityManagerNative.getDefault();
2693 final int callingUserId = UserHandle.getCallingUserId();
2694 final long ident = Binder.clearCallingIdentity();
2696 //XXX we should only revoke for the calling user's app permissions,
2697 // but for now we impact all users.
2698 //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2699 // "revoke " + permissionName);
2700 int[] users = sUserManager.getUserIds();
2701 for (int user : users) {
2702 am.killUid(UserHandle.getUid(user, changedAppId),
2703 "revoke " + permissionName);
2705 } catch (RemoteException e) {
2707 Binder.restoreCallingIdentity(ident);
2714 public boolean isProtectedBroadcast(String actionName) {
2715 synchronized (mPackages) {
2716 return mProtectedBroadcasts.contains(actionName);
2721 public int checkSignatures(String pkg1, String pkg2) {
2722 synchronized (mPackages) {
2723 final PackageParser.Package p1 = mPackages.get(pkg1);
2724 final PackageParser.Package p2 = mPackages.get(pkg2);
2725 if (p1 == null || p1.mExtras == null
2726 || p2 == null || p2.mExtras == null) {
2727 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2729 return compareSignatures(p1.mSignatures, p2.mSignatures);
2734 public int checkUidSignatures(int uid1, int uid2) {
2735 // Map to base uids.
2736 uid1 = UserHandle.getAppId(uid1);
2737 uid2 = UserHandle.getAppId(uid2);
2739 synchronized (mPackages) {
2742 Object obj = mSettings.getUserIdLPr(uid1);
2744 if (obj instanceof SharedUserSetting) {
2745 s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2746 } else if (obj instanceof PackageSetting) {
2747 s1 = ((PackageSetting)obj).signatures.mSignatures;
2749 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2752 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2754 obj = mSettings.getUserIdLPr(uid2);
2756 if (obj instanceof SharedUserSetting) {
2757 s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2758 } else if (obj instanceof PackageSetting) {
2759 s2 = ((PackageSetting)obj).signatures.mSignatures;
2761 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2764 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2766 return compareSignatures(s1, s2);
2771 * Compares two sets of signatures. Returns:
2773 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
2775 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
2777 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
2779 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
2781 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
2783 static int compareSignatures(Signature[] s1, Signature[] s2) {
2786 ? PackageManager.SIGNATURE_NEITHER_SIGNED
2787 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2791 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2794 if (s1.length != s2.length) {
2795 return PackageManager.SIGNATURE_NO_MATCH;
2798 // Since both signature sets are of size 1, we can compare without HashSets.
2799 if (s1.length == 1) {
2800 return s1[0].equals(s2[0]) ?
2801 PackageManager.SIGNATURE_MATCH :
2802 PackageManager.SIGNATURE_NO_MATCH;
2805 ArraySet<Signature> set1 = new ArraySet<Signature>();
2806 for (Signature sig : s1) {
2809 ArraySet<Signature> set2 = new ArraySet<Signature>();
2810 for (Signature sig : s2) {
2813 // Make sure s2 contains all signatures in s1.
2814 if (set1.equals(set2)) {
2815 return PackageManager.SIGNATURE_MATCH;
2817 return PackageManager.SIGNATURE_NO_MATCH;
2821 * If the database version for this type of package (internal storage or
2822 * external storage) is less than the version where package signatures
2823 * were updated, return true.
2825 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
2826 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
2827 DatabaseVersion.SIGNATURE_END_ENTITY))
2828 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
2829 DatabaseVersion.SIGNATURE_END_ENTITY));
2833 * Used for backward compatibility to make sure any packages with
2834 * certificate chains get upgraded to the new style. {@code existingSigs}
2835 * will be in the old format (since they were stored on disk from before the
2836 * system upgrade) and {@code scannedSigs} will be in the newer format.
2838 private int compareSignaturesCompat(PackageSignatures existingSigs,
2839 PackageParser.Package scannedPkg) {
2840 if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
2841 return PackageManager.SIGNATURE_NO_MATCH;
2844 ArraySet<Signature> existingSet = new ArraySet<Signature>();
2845 for (Signature sig : existingSigs.mSignatures) {
2846 existingSet.add(sig);
2848 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
2849 for (Signature sig : scannedPkg.mSignatures) {
2851 Signature[] chainSignatures = sig.getChainSignatures();
2852 for (Signature chainSig : chainSignatures) {
2853 scannedCompatSet.add(chainSig);
2855 } catch (CertificateEncodingException e) {
2856 scannedCompatSet.add(sig);
2860 * Make sure the expanded scanned set contains all signatures in the
2863 if (scannedCompatSet.equals(existingSet)) {
2864 // Migrate the old signatures to the new scheme.
2865 existingSigs.assignSignatures(scannedPkg.mSignatures);
2866 // The new KeySets will be re-added later in the scanning process.
2867 synchronized (mPackages) {
2868 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
2870 return PackageManager.SIGNATURE_MATCH;
2872 return PackageManager.SIGNATURE_NO_MATCH;
2876 public String[] getPackagesForUid(int uid) {
2877 uid = UserHandle.getAppId(uid);
2879 synchronized (mPackages) {
2880 Object obj = mSettings.getUserIdLPr(uid);
2881 if (obj instanceof SharedUserSetting) {
2882 final SharedUserSetting sus = (SharedUserSetting) obj;
2883 final int N = sus.packages.size();
2884 final String[] res = new String[N];
2885 final Iterator<PackageSetting> it = sus.packages.iterator();
2887 while (it.hasNext()) {
2888 res[i++] = it.next().name;
2891 } else if (obj instanceof PackageSetting) {
2892 final PackageSetting ps = (PackageSetting) obj;
2893 return new String[] { ps.name };
2900 public String getNameForUid(int uid) {
2902 synchronized (mPackages) {
2903 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2904 if (obj instanceof SharedUserSetting) {
2905 final SharedUserSetting sus = (SharedUserSetting) obj;
2906 return sus.name + ":" + sus.userId;
2907 } else if (obj instanceof PackageSetting) {
2908 final PackageSetting ps = (PackageSetting) obj;
2916 public int getUidForSharedUser(String sharedUserName) {
2917 if(sharedUserName == null) {
2921 synchronized (mPackages) {
2922 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2931 public int getFlagsForUid(int uid) {
2932 synchronized (mPackages) {
2933 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2934 if (obj instanceof SharedUserSetting) {
2935 final SharedUserSetting sus = (SharedUserSetting) obj;
2936 return sus.pkgFlags;
2937 } else if (obj instanceof PackageSetting) {
2938 final PackageSetting ps = (PackageSetting) obj;
2946 public boolean isUidPrivileged(int uid) {
2947 uid = UserHandle.getAppId(uid);
2949 synchronized (mPackages) {
2950 Object obj = mSettings.getUserIdLPr(uid);
2951 if (obj instanceof SharedUserSetting) {
2952 final SharedUserSetting sus = (SharedUserSetting) obj;
2953 final Iterator<PackageSetting> it = sus.packages.iterator();
2954 while (it.hasNext()) {
2955 if (it.next().isPrivileged()) {
2959 } else if (obj instanceof PackageSetting) {
2960 final PackageSetting ps = (PackageSetting) obj;
2961 return ps.isPrivileged();
2968 public String[] getAppOpPermissionPackages(String permissionName) {
2969 synchronized (mPackages) {
2970 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
2974 return pkgs.toArray(new String[pkgs.size()]);
2979 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2980 int flags, int userId) {
2981 if (!sUserManager.exists(userId)) return null;
2982 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
2983 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2984 return chooseBestActivity(intent, resolvedType, flags, query, userId);
2988 public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
2989 IntentFilter filter, int match, ComponentName activity) {
2990 final int userId = UserHandle.getCallingUserId();
2991 if (DEBUG_PREFERRED) {
2992 Log.v(TAG, "setLastChosenActivity intent=" + intent
2993 + " resolvedType=" + resolvedType
2995 + " filter=" + filter
2997 + " activity=" + activity);
2998 filter.dump(new PrintStreamPrinter(System.out), " ");
3000 intent.setComponent(null);
3001 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3002 // Find any earlier preferred or last chosen entries and nuke them
3003 findPreferredActivity(intent, resolvedType,
3004 flags, query, 0, false, true, false, userId);
3005 // Add the new activity as the last chosen for this filter
3006 addPreferredActivityInternal(filter, match, null, activity, false, userId,
3007 "Setting last chosen");
3011 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
3012 final int userId = UserHandle.getCallingUserId();
3013 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
3014 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3015 return findPreferredActivity(intent, resolvedType, flags, query, 0,
3016 false, false, false, userId);
3019 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
3020 int flags, List<ResolveInfo> query, int userId) {
3021 if (query != null) {
3022 final int N = query.size();
3024 return query.get(0);
3026 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3027 // If there is more than one activity with the same priority,
3028 // then let the user decide between them.
3029 ResolveInfo r0 = query.get(0);
3030 ResolveInfo r1 = query.get(1);
3031 if (DEBUG_INTENT_MATCHING || debug) {
3032 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
3033 + r1.activityInfo.name + "=" + r1.priority);
3035 // If the first activity has a higher priority, or a different
3036 // default, then it is always desireable to pick it.
3037 if (r0.priority != r1.priority
3038 || r0.preferredOrder != r1.preferredOrder
3039 || r0.isDefault != r1.isDefault) {
3040 return query.get(0);
3042 // If we have saved a preference for a preferred activity for
3043 // this Intent, use that.
3044 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
3045 flags, query, r0.priority, true, false, debug, userId);
3050 ri = new ResolveInfo(mResolveInfo);
3051 ri.activityInfo = new ActivityInfo(ri.activityInfo);
3052 ri.activityInfo.applicationInfo = new ApplicationInfo(
3053 ri.activityInfo.applicationInfo);
3054 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
3055 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
3058 return mResolveInfo;
3064 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
3065 int flags, List<ResolveInfo> query, boolean debug, int userId) {
3066 final int N = query.size();
3067 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
3069 // Get the list of persistent preferred activities that handle the intent
3070 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
3071 List<PersistentPreferredActivity> pprefs = ppir != null
3072 ? ppir.queryIntent(intent, resolvedType,
3073 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3075 if (pprefs != null && pprefs.size() > 0) {
3076 final int M = pprefs.size();
3077 for (int i=0; i<M; i++) {
3078 final PersistentPreferredActivity ppa = pprefs.get(i);
3079 if (DEBUG_PREFERRED || debug) {
3080 Slog.v(TAG, "Checking PersistentPreferredActivity ds="
3081 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
3082 + "\n component=" + ppa.mComponent);
3083 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3085 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
3086 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3087 if (DEBUG_PREFERRED || debug) {
3088 Slog.v(TAG, "Found persistent preferred activity:");
3090 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3092 Slog.v(TAG, " null");
3096 // This previously registered persistent preferred activity
3097 // component is no longer known. Ignore it and do NOT remove it.
3100 for (int j=0; j<N; j++) {
3101 final ResolveInfo ri = query.get(j);
3102 if (!ri.activityInfo.applicationInfo.packageName
3103 .equals(ai.applicationInfo.packageName)) {
3106 if (!ri.activityInfo.name.equals(ai.name)) {
3109 // Found a persistent preference that can handle the intent.
3110 if (DEBUG_PREFERRED || debug) {
3111 Slog.v(TAG, "Returning persistent preferred activity: " +
3112 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3121 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
3122 List<ResolveInfo> query, int priority, boolean always,
3123 boolean removeMatches, boolean debug, int userId) {
3124 if (!sUserManager.exists(userId)) return null;
3126 synchronized (mPackages) {
3127 if (intent.getSelector() != null) {
3128 intent = intent.getSelector();
3130 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
3132 // Try to find a matching persistent preferred activity.
3133 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
3136 // If a persistent preferred activity matched, use it.
3141 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
3142 // Get the list of preferred activities that handle the intent
3143 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
3144 List<PreferredActivity> prefs = pir != null
3145 ? pir.queryIntent(intent, resolvedType,
3146 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3148 if (prefs != null && prefs.size() > 0) {
3149 boolean changed = false;
3151 // First figure out how good the original match set is.
3152 // We will only allow preferred activities that came
3153 // from the same match quality.
3156 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
3158 final int N = query.size();
3159 for (int j=0; j<N; j++) {
3160 final ResolveInfo ri = query.get(j);
3161 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
3162 + ": 0x" + Integer.toHexString(match));
3163 if (ri.match > match) {
3168 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
3169 + Integer.toHexString(match));
3171 match &= IntentFilter.MATCH_CATEGORY_MASK;
3172 final int M = prefs.size();
3173 for (int i=0; i<M; i++) {
3174 final PreferredActivity pa = prefs.get(i);
3175 if (DEBUG_PREFERRED || debug) {
3176 Slog.v(TAG, "Checking PreferredActivity ds="
3177 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
3178 + "\n component=" + pa.mPref.mComponent);
3179 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3181 if (pa.mPref.mMatch != match) {
3182 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
3183 + Integer.toHexString(pa.mPref.mMatch));
3186 // If it's not an "always" type preferred activity and that's what we're
3187 // looking for, skip it.
3188 if (always && !pa.mPref.mAlways) {
3189 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
3192 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
3193 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3194 if (DEBUG_PREFERRED || debug) {
3195 Slog.v(TAG, "Found preferred activity:");
3197 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
3199 Slog.v(TAG, " null");
3203 // This previously registered preferred activity
3204 // component is no longer known. Most likely an update
3205 // to the app was installed and in the new version this
3206 // component no longer exists. Clean it up by removing
3207 // it from the preferred activities list, and skip it.
3208 Slog.w(TAG, "Removing dangling preferred activity: "
3209 + pa.mPref.mComponent);
3210 pir.removeFilter(pa);
3214 for (int j=0; j<N; j++) {
3215 final ResolveInfo ri = query.get(j);
3216 if (!ri.activityInfo.applicationInfo.packageName
3217 .equals(ai.applicationInfo.packageName)) {
3220 if (!ri.activityInfo.name.equals(ai.name)) {
3224 if (removeMatches) {
3225 pir.removeFilter(pa);
3227 if (DEBUG_PREFERRED) {
3228 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
3233 // Okay we found a previously set preferred or last chosen app.
3234 // If the result set is different from when this
3235 // was created, we need to clear it and re-ask the
3236 // user their preference, if we're looking for an "always" type entry.
3237 if (always && !pa.mPref.sameSet(query, priority)) {
3238 Slog.i(TAG, "Result set changed, dropping preferred activity for "
3239 + intent + " type " + resolvedType);
3240 if (DEBUG_PREFERRED) {
3241 Slog.v(TAG, "Removing preferred activity since set changed "
3242 + pa.mPref.mComponent);
3244 pir.removeFilter(pa);
3245 // Re-add the filter as a "last chosen" entry (!always)
3246 PreferredActivity lastChosen = new PreferredActivity(
3247 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
3248 pir.addFilter(lastChosen);
3253 // Yay! Either the set matched or we're looking for the last chosen
3254 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
3255 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3261 if (DEBUG_PREFERRED) {
3262 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
3264 scheduleWritePackageRestrictionsLocked(userId);
3269 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
3274 * Returns if intent can be forwarded from the sourceUserId to the targetUserId
3277 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
3279 mContext.enforceCallingOrSelfPermission(
3280 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
3281 List<CrossProfileIntentFilter> matches =
3282 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
3283 if (matches != null) {
3284 int size = matches.size();
3285 for (int i = 0; i < size; i++) {
3286 if (matches.get(i).getTargetUserId() == targetUserId) return true;
3292 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
3293 String resolvedType, int userId) {
3294 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
3295 if (resolver != null) {
3296 return resolver.queryIntent(intent, resolvedType, false, userId);
3302 public List<ResolveInfo> queryIntentActivities(Intent intent,
3303 String resolvedType, int flags, int userId) {
3304 if (!sUserManager.exists(userId)) return Collections.emptyList();
3305 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
3306 ComponentName comp = intent.getComponent();
3308 if (intent.getSelector() != null) {
3309 intent = intent.getSelector();
3310 comp = intent.getComponent();
3315 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3316 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
3318 final ResolveInfo ri = new ResolveInfo();
3319 ri.activityInfo = ai;
3326 synchronized (mPackages) {
3327 final String pkgName = intent.getPackage();
3328 if (pkgName == null) {
3329 List<CrossProfileIntentFilter> matchingFilters =
3330 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
3331 // Check for results that need to skip the current profile.
3332 ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
3333 resolvedType, flags, userId);
3334 if (resolveInfo != null) {
3335 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
3336 result.add(resolveInfo);
3339 // Check for cross profile results.
3340 resolveInfo = queryCrossProfileIntents(
3341 matchingFilters, intent, resolvedType, flags, userId);
3343 // Check for results in the current profile.
3344 List<ResolveInfo> result = mActivities.queryIntent(
3345 intent, resolvedType, flags, userId);
3346 if (resolveInfo != null) {
3347 result.add(resolveInfo);
3348 Collections.sort(result, mResolvePrioritySorter);
3352 final PackageParser.Package pkg = mPackages.get(pkgName);
3354 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
3355 pkg.activities, userId);
3357 return new ArrayList<ResolveInfo>();
3361 private ResolveInfo querySkipCurrentProfileIntents(
3362 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3363 int flags, int sourceUserId) {
3364 if (matchingFilters != null) {
3365 int size = matchingFilters.size();
3366 for (int i = 0; i < size; i ++) {
3367 CrossProfileIntentFilter filter = matchingFilters.get(i);
3368 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
3369 // Checking if there are activities in the target user that can handle the
3371 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3372 flags, sourceUserId);
3373 if (resolveInfo != null) {
3382 // Return matching ResolveInfo if any for skip current profile intent filters.
3383 private ResolveInfo queryCrossProfileIntents(
3384 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3385 int flags, int sourceUserId) {
3386 if (matchingFilters != null) {
3387 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
3388 // match the same intent. For performance reasons, it is better not to
3389 // run queryIntent twice for the same userId
3390 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
3391 int size = matchingFilters.size();
3392 for (int i = 0; i < size; i++) {
3393 CrossProfileIntentFilter filter = matchingFilters.get(i);
3394 int targetUserId = filter.getTargetUserId();
3395 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
3396 && !alreadyTriedUserIds.get(targetUserId)) {
3397 // Checking if there are activities in the target user that can handle the
3399 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3400 flags, sourceUserId);
3401 if (resolveInfo != null) return resolveInfo;
3402 alreadyTriedUserIds.put(targetUserId, true);
3409 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
3410 String resolvedType, int flags, int sourceUserId) {
3411 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
3412 resolvedType, flags, filter.getTargetUserId());
3413 if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
3414 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
3419 private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
3420 int sourceUserId, int targetUserId) {
3421 ResolveInfo forwardingResolveInfo = new ResolveInfo();
3423 if (targetUserId == UserHandle.USER_OWNER) {
3424 className = FORWARD_INTENT_TO_USER_OWNER;
3426 className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3428 ComponentName forwardingActivityComponentName = new ComponentName(
3429 mAndroidApplication.packageName, className);
3430 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
3432 if (targetUserId == UserHandle.USER_OWNER) {
3433 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
3434 forwardingResolveInfo.noResourceId = true;
3436 forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3437 forwardingResolveInfo.priority = 0;
3438 forwardingResolveInfo.preferredOrder = 0;
3439 forwardingResolveInfo.match = 0;
3440 forwardingResolveInfo.isDefault = true;
3441 forwardingResolveInfo.filter = filter;
3442 forwardingResolveInfo.targetUserId = targetUserId;
3443 return forwardingResolveInfo;
3447 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
3448 Intent[] specifics, String[] specificTypes, Intent intent,
3449 String resolvedType, int flags, int userId) {
3450 if (!sUserManager.exists(userId)) return Collections.emptyList();
3451 enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
3452 false, "query intent activity options");
3453 final String resultsAction = intent.getAction();
3455 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
3456 | PackageManager.GET_RESOLVED_FILTER, userId);
3458 if (DEBUG_INTENT_MATCHING) {
3459 Log.v(TAG, "Query " + intent + ": " + results);
3462 int specificsPos = 0;
3465 // todo: note that the algorithm used here is O(N^2). This
3466 // isn't a problem in our current environment, but if we start running
3467 // into situations where we have more than 5 or 10 matches then this
3468 // should probably be changed to something smarter...
3470 // First we go through and resolve each of the specific items
3471 // that were supplied, taking care of removing any corresponding
3472 // duplicate items in the generic resolve list.
3473 if (specifics != null) {
3474 for (int i=0; i<specifics.length; i++) {
3475 final Intent sintent = specifics[i];
3476 if (sintent == null) {
3480 if (DEBUG_INTENT_MATCHING) {
3481 Log.v(TAG, "Specific #" + i + ": " + sintent);
3484 String action = sintent.getAction();
3485 if (resultsAction != null && resultsAction.equals(action)) {
3486 // If this action was explicitly requested, then don't
3487 // remove things that have it.
3491 ResolveInfo ri = null;
3492 ActivityInfo ai = null;
3494 ComponentName comp = sintent.getComponent();
3498 specificTypes != null ? specificTypes[i] : null,
3503 if (ri == mResolveInfo) {
3504 // ACK! Must do something better with this.
3506 ai = ri.activityInfo;
3507 comp = new ComponentName(ai.applicationInfo.packageName,
3510 ai = getActivityInfo(comp, flags, userId);
3516 // Look for any generic query activities that are duplicates
3517 // of this specific one, and remove them from the results.
3518 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
3521 for (j=specificsPos; j<N; j++) {
3522 ResolveInfo sri = results.get(j);
3523 if ((sri.activityInfo.name.equals(comp.getClassName())
3524 && sri.activityInfo.applicationInfo.packageName.equals(
3525 comp.getPackageName()))
3526 || (action != null && sri.filter.matchAction(action))) {
3528 if (DEBUG_INTENT_MATCHING) Log.v(
3529 TAG, "Removing duplicate item from " + j
3530 + " due to specific " + specificsPos);
3539 // Add this specific item to its proper place.
3541 ri = new ResolveInfo();
3542 ri.activityInfo = ai;
3544 results.add(specificsPos, ri);
3545 ri.specificIndex = i;
3550 // Now we go through the remaining generic results and remove any
3551 // duplicate actions that are found here.
3553 for (int i=specificsPos; i<N-1; i++) {
3554 final ResolveInfo rii = results.get(i);
3555 if (rii.filter == null) {
3559 // Iterate over all of the actions of this result's intent
3560 // filter... typically this should be just one.
3561 final Iterator<String> it = rii.filter.actionsIterator();
3565 while (it.hasNext()) {
3566 final String action = it.next();
3567 if (resultsAction != null && resultsAction.equals(action)) {
3568 // If this action was explicitly requested, then don't
3569 // remove things that have it.
3572 for (int j=i+1; j<N; j++) {
3573 final ResolveInfo rij = results.get(j);
3574 if (rij.filter != null && rij.filter.hasAction(action)) {
3576 if (DEBUG_INTENT_MATCHING) Log.v(
3577 TAG, "Removing duplicate item from " + j
3578 + " due to action " + action + " at " + i);
3585 // If the caller didn't request filter information, drop it now
3586 // so we don't have to marshall/unmarshall it.
3587 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3592 // Filter out the caller activity if so requested.
3593 if (caller != null) {
3595 for (int i=0; i<N; i++) {
3596 ActivityInfo ainfo = results.get(i).activityInfo;
3597 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
3598 && caller.getClassName().equals(ainfo.name)) {
3605 // If the caller didn't request filter information,
3606 // drop them now so we don't have to
3607 // marshall/unmarshall it.
3608 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3610 for (int i=0; i<N; i++) {
3611 results.get(i).filter = null;
3615 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
3620 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
3622 if (!sUserManager.exists(userId)) return Collections.emptyList();
3623 ComponentName comp = intent.getComponent();
3625 if (intent.getSelector() != null) {
3626 intent = intent.getSelector();
3627 comp = intent.getComponent();
3631 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3632 ActivityInfo ai = getReceiverInfo(comp, flags, userId);
3634 ResolveInfo ri = new ResolveInfo();
3635 ri.activityInfo = ai;
3642 synchronized (mPackages) {
3643 String pkgName = intent.getPackage();
3644 if (pkgName == null) {
3645 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
3647 final PackageParser.Package pkg = mPackages.get(pkgName);
3649 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
3657 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
3658 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
3659 if (!sUserManager.exists(userId)) return null;
3660 if (query != null) {
3661 if (query.size() >= 1) {
3662 // If there is more than one service with the same priority,
3663 // just arbitrarily pick the first one.
3664 return query.get(0);
3671 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
3673 if (!sUserManager.exists(userId)) return Collections.emptyList();
3674 ComponentName comp = intent.getComponent();
3676 if (intent.getSelector() != null) {
3677 intent = intent.getSelector();
3678 comp = intent.getComponent();
3682 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3683 final ServiceInfo si = getServiceInfo(comp, flags, userId);
3685 final ResolveInfo ri = new ResolveInfo();
3686 ri.serviceInfo = si;
3693 synchronized (mPackages) {
3694 String pkgName = intent.getPackage();
3695 if (pkgName == null) {
3696 return mServices.queryIntent(intent, resolvedType, flags, userId);
3698 final PackageParser.Package pkg = mPackages.get(pkgName);
3700 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3708 public List<ResolveInfo> queryIntentContentProviders(
3709 Intent intent, String resolvedType, int flags, int userId) {
3710 if (!sUserManager.exists(userId)) return Collections.emptyList();
3711 ComponentName comp = intent.getComponent();
3713 if (intent.getSelector() != null) {
3714 intent = intent.getSelector();
3715 comp = intent.getComponent();
3719 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3720 final ProviderInfo pi = getProviderInfo(comp, flags, userId);
3722 final ResolveInfo ri = new ResolveInfo();
3723 ri.providerInfo = pi;
3730 synchronized (mPackages) {
3731 String pkgName = intent.getPackage();
3732 if (pkgName == null) {
3733 return mProviders.queryIntent(intent, resolvedType, flags, userId);
3735 final PackageParser.Package pkg = mPackages.get(pkgName);
3737 return mProviders.queryIntentForPackage(
3738 intent, resolvedType, flags, pkg.providers, userId);
3745 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3746 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3748 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
3751 synchronized (mPackages) {
3752 ArrayList<PackageInfo> list;
3753 if (listUninstalled) {
3754 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3755 for (PackageSetting ps : mSettings.mPackages.values()) {
3757 if (ps.pkg != null) {
3758 pi = generatePackageInfo(ps.pkg, flags, userId);
3760 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3767 list = new ArrayList<PackageInfo>(mPackages.size());
3768 for (PackageParser.Package p : mPackages.values()) {
3769 PackageInfo pi = generatePackageInfo(p, flags, userId);
3776 return new ParceledListSlice<PackageInfo>(list);
3780 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3781 String[] permissions, boolean[] tmp, int flags, int userId) {
3783 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3784 for (int i=0; i<permissions.length; i++) {
3785 if (gp.grantedPermissions.contains(permissions[i])) {
3792 if (numMatch == 0) {
3796 if (ps.pkg != null) {
3797 pi = generatePackageInfo(ps.pkg, flags, userId);
3799 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3801 // The above might return null in cases of uninstalled apps or install-state
3802 // skew across users/profiles.
3804 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3805 if (numMatch == permissions.length) {
3806 pi.requestedPermissions = permissions;
3808 pi.requestedPermissions = new String[numMatch];
3810 for (int i=0; i<permissions.length; i++) {
3812 pi.requestedPermissions[numMatch] = permissions[i];
3823 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3824 String[] permissions, int flags, int userId) {
3825 if (!sUserManager.exists(userId)) return null;
3826 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3829 synchronized (mPackages) {
3830 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3831 boolean[] tmpBools = new boolean[permissions.length];
3832 if (listUninstalled) {
3833 for (PackageSetting ps : mSettings.mPackages.values()) {
3834 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3837 for (PackageParser.Package pkg : mPackages.values()) {
3838 PackageSetting ps = (PackageSetting)pkg.mExtras;
3840 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3846 return new ParceledListSlice<PackageInfo>(list);
3851 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3852 if (!sUserManager.exists(userId)) return null;
3853 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3856 synchronized (mPackages) {
3857 ArrayList<ApplicationInfo> list;
3858 if (listUninstalled) {
3859 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3860 for (PackageSetting ps : mSettings.mPackages.values()) {
3862 if (ps.pkg != null) {
3863 ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3864 ps.readUserState(userId), userId);
3866 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3873 list = new ArrayList<ApplicationInfo>(mPackages.size());
3874 for (PackageParser.Package p : mPackages.values()) {
3875 if (p.mExtras != null) {
3876 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3877 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3885 return new ParceledListSlice<ApplicationInfo>(list);
3889 public List<ApplicationInfo> getPersistentApplications(int flags) {
3890 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3893 synchronized (mPackages) {
3894 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3895 final int userId = UserHandle.getCallingUserId();
3896 while (i.hasNext()) {
3897 final PackageParser.Package p = i.next();
3898 if (p.applicationInfo != null
3899 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3900 && (!mSafeMode || isSystemApp(p))) {
3901 PackageSetting ps = mSettings.mPackages.get(p.packageName);
3903 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3904 ps.readUserState(userId), userId);
3917 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3918 if (!sUserManager.exists(userId)) return null;
3920 synchronized (mPackages) {
3921 final PackageParser.Provider provider = mProvidersByAuthority.get(name);
3922 PackageSetting ps = provider != null
3923 ? mSettings.mPackages.get(provider.owner.packageName)
3926 && mSettings.isEnabledLPr(provider.info, flags, userId)
3927 && (!mSafeMode || (provider.info.applicationInfo.flags
3928 &ApplicationInfo.FLAG_SYSTEM) != 0)
3929 ? PackageParser.generateProviderInfo(provider, flags,
3930 ps.readUserState(userId), userId)
3939 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3941 synchronized (mPackages) {
3942 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
3943 .entrySet().iterator();
3944 final int userId = UserHandle.getCallingUserId();
3945 while (i.hasNext()) {
3946 Map.Entry<String, PackageParser.Provider> entry = i.next();
3947 PackageParser.Provider p = entry.getValue();
3948 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3950 if (ps != null && p.syncable
3951 && (!mSafeMode || (p.info.applicationInfo.flags
3952 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3953 ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3954 ps.readUserState(userId), userId);
3956 outNames.add(entry.getKey());
3965 public List<ProviderInfo> queryContentProviders(String processName,
3966 int uid, int flags) {
3967 ArrayList<ProviderInfo> finalList = null;
3969 synchronized (mPackages) {
3970 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
3971 final int userId = processName != null ?
3972 UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3973 while (i.hasNext()) {
3974 final PackageParser.Provider p = i.next();
3975 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3976 if (ps != null && p.info.authority != null
3977 && (processName == null
3978 || (p.info.processName.equals(processName)
3979 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3980 && mSettings.isEnabledLPr(p.info, flags, userId)
3982 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3983 if (finalList == null) {
3984 finalList = new ArrayList<ProviderInfo>(3);
3986 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3987 ps.readUserState(userId), userId);
3989 finalList.add(info);
3995 if (finalList != null) {
3996 Collections.sort(finalList, mProviderInitOrderSorter);
4003 public InstrumentationInfo getInstrumentationInfo(ComponentName name,
4006 synchronized (mPackages) {
4007 final PackageParser.Instrumentation i = mInstrumentation.get(name);
4008 return PackageParser.generateInstrumentationInfo(i, flags);
4013 public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
4015 ArrayList<InstrumentationInfo> finalList =
4016 new ArrayList<InstrumentationInfo>();
4019 synchronized (mPackages) {
4020 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
4021 while (i.hasNext()) {
4022 final PackageParser.Instrumentation p = i.next();
4023 if (targetPackage == null
4024 || targetPackage.equals(p.info.targetPackage)) {
4025 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
4037 private void createIdmapsForPackageLI(PackageParser.Package pkg) {
4038 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
4039 if (overlays == null) {
4040 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
4043 for (PackageParser.Package opkg : overlays.values()) {
4044 // Not much to do if idmap fails: we already logged the error
4045 // and we certainly don't want to abort installation of pkg simply
4046 // because an overlay didn't fit properly. For these reasons,
4047 // ignore the return value of createIdmapForPackagePairLI.
4048 createIdmapForPackagePairLI(pkg, opkg);
4052 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
4053 PackageParser.Package opkg) {
4054 if (!opkg.mTrustedOverlay) {
4055 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
4056 opkg.baseCodePath + ": overlay not trusted");
4059 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
4060 if (overlaySet == null) {
4061 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
4062 opkg.baseCodePath + " but target package has no known overlays");
4065 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4066 // TODO: generate idmap for split APKs
4067 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
4068 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
4069 + opkg.baseCodePath);
4072 PackageParser.Package[] overlayArray =
4073 overlaySet.values().toArray(new PackageParser.Package[0]);
4074 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
4075 public int compare(PackageParser.Package p1, PackageParser.Package p2) {
4076 return p1.mOverlayPriority - p2.mOverlayPriority;
4079 Arrays.sort(overlayArray, cmp);
4081 pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
4083 for (PackageParser.Package p : overlayArray) {
4084 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
4089 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
4090 final File[] files = dir.listFiles();
4091 if (ArrayUtils.isEmpty(files)) {
4092 Log.d(TAG, "No files in app dir " + dir);
4096 if (DEBUG_PACKAGE_SCANNING) {
4097 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
4098 + " flags=0x" + Integer.toHexString(parseFlags));
4101 for (File file : files) {
4102 final boolean isPackage = (isApkFile(file) || file.isDirectory())
4103 && !PackageInstallerService.isStageName(file.getName());
4105 // Ignore entries which are not packages
4109 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
4110 scanFlags, currentTime, null);
4111 } catch (PackageManagerException e) {
4112 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
4114 // Delete invalid userdata apps
4115 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
4116 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
4117 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
4118 if (file.isDirectory()) {
4119 FileUtils.deleteContents(file);
4127 private static File getSettingsProblemFile() {
4128 File dataDir = Environment.getDataDirectory();
4129 File systemDir = new File(dataDir, "system");
4130 File fname = new File(systemDir, "uiderrors.txt");
4134 static void reportSettingsProblem(int priority, String msg) {
4135 logCriticalInfo(priority, msg);
4138 static void logCriticalInfo(int priority, String msg) {
4139 Slog.println(priority, TAG, msg);
4140 EventLogTags.writePmCriticalInfo(msg);
4142 File fname = getSettingsProblemFile();
4143 FileOutputStream out = new FileOutputStream(fname, true);
4144 PrintWriter pw = new FastPrintWriter(out);
4145 SimpleDateFormat formatter = new SimpleDateFormat();
4146 String dateString = formatter.format(new Date(System.currentTimeMillis()));
4147 pw.println(dateString + ": " + msg);
4149 FileUtils.setPermissions(
4151 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
4153 } catch (java.io.IOException e) {
4157 private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
4158 PackageParser.Package pkg, File srcFile, int parseFlags)
4159 throws PackageManagerException {
4161 && ps.codePath.equals(srcFile)
4162 && ps.timeStamp == srcFile.lastModified()
4163 && !isCompatSignatureUpdateNeeded(pkg)) {
4164 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
4165 if (ps.signatures.mSignatures != null
4166 && ps.signatures.mSignatures.length != 0
4167 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
4168 // Optimization: reuse the existing cached certificates
4169 // if the package appears to be unchanged.
4170 pkg.mSignatures = ps.signatures.mSignatures;
4171 KeySetManagerService ksms = mSettings.mKeySetManagerService;
4172 synchronized (mPackages) {
4173 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
4178 Slog.w(TAG, "PackageSetting for " + ps.name
4179 + " is missing signatures. Collecting certs again to recover them.");
4181 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
4185 pp.collectCertificates(pkg, parseFlags);
4186 pp.collectManifestDigest(pkg);
4187 } catch (PackageParserException e) {
4188 throw PackageManagerException.from(e);
4193 * Scan a package and return the newly parsed package.
4194 * Returns null in case of errors and the error code is stored in mLastScanError
4196 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
4197 long currentTime, UserHandle user) throws PackageManagerException {
4198 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
4199 parseFlags |= mDefParseFlags;
4200 PackageParser pp = new PackageParser();
4201 pp.setSeparateProcesses(mSeparateProcesses);
4202 pp.setOnlyCoreApps(mOnlyCore);
4203 pp.setDisplayMetrics(mMetrics);
4205 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
4206 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
4209 final PackageParser.Package pkg;
4211 pkg = pp.parsePackage(scanFile, parseFlags);
4212 } catch (PackageParserException e) {
4213 throw PackageManagerException.from(e);
4216 PackageSetting ps = null;
4217 PackageSetting updatedPkg;
4219 synchronized (mPackages) {
4220 // Look to see if we already know about this package.
4221 String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
4222 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
4223 // This package has been renamed to its original name. Let's
4225 ps = mSettings.peekPackageLPr(oldName);
4227 // If there was no original package, see one for the real package name.
4229 ps = mSettings.peekPackageLPr(pkg.packageName);
4231 // Check to see if this package could be hiding/updating a system
4232 // package. Must look for it either under the original or real
4233 // package name depending on our state.
4234 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
4235 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
4237 boolean updatedPkgBetter = false;
4238 // First check if this is a system package that may involve an update
4239 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4240 if (ps != null && !ps.codePath.equals(scanFile)) {
4241 // The path has changed from what was last scanned... check the
4242 // version of the new path against what we have stored to determine
4244 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
4245 if (pkg.mVersionCode < ps.versionCode) {
4246 // The system package has been updated and the code path does not match
4247 // Ignore entry. Skip it.
4248 logCriticalInfo(Log.INFO, "Package " + ps.name + " at " + scanFile
4249 + " ignored: updated version " + ps.versionCode
4250 + " better than this " + pkg.mVersionCode);
4251 if (!updatedPkg.codePath.equals(scanFile)) {
4252 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
4253 + ps.name + " changing from " + updatedPkg.codePathString
4254 + " to " + scanFile);
4255 updatedPkg.codePath = scanFile;
4256 updatedPkg.codePathString = scanFile.toString();
4257 // This is the point at which we know that the system-disk APK
4258 // for this package has moved during a reboot (e.g. due to an OTA),
4259 // so we need to reevaluate it for privilege policy.
4260 if (locationIsPrivileged(scanFile)) {
4261 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
4264 updatedPkg.pkg = pkg;
4265 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
4267 // The current app on the system partition is better than
4268 // what we have updated to on the data partition; switch
4269 // back to the system partition version.
4270 // At this point, its safely assumed that package installation for
4271 // apps in system partition will go through. If not there won't be a working
4272 // version of the app
4274 synchronized (mPackages) {
4275 // Just remove the loaded entries from package lists.
4276 mPackages.remove(ps.name);
4279 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4280 + " reverting from " + ps.codePathString
4281 + ": new version " + pkg.mVersionCode
4282 + " better than installed " + ps.versionCode);
4284 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4285 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4286 getAppDexInstructionSets(ps));
4287 synchronized (mInstallLock) {
4288 args.cleanUpResourcesLI();
4290 synchronized (mPackages) {
4291 mSettings.enableSystemPackageLPw(ps.name);
4293 updatedPkgBetter = true;
4298 if (updatedPkg != null) {
4299 // An updated system app will not have the PARSE_IS_SYSTEM flag set
4301 parseFlags |= PackageParser.PARSE_IS_SYSTEM;
4303 // An updated privileged app will not have the PARSE_IS_PRIVILEGED
4304 // flag set initially
4305 if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
4306 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
4310 // Verify certificates against what was last scanned
4311 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
4314 * A new system app appeared, but we already had a non-system one of the
4315 * same name installed earlier.
4317 boolean shouldHideSystemApp = false;
4318 if (updatedPkg == null && ps != null
4319 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
4321 * Check to make sure the signatures match first. If they don't,
4322 * wipe the installed application and its data.
4324 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
4325 != PackageManager.SIGNATURE_MATCH) {
4326 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
4327 + " signatures don't match existing userdata copy; removing");
4328 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
4332 * If the newly-added system app is an older version than the
4333 * already installed version, hide it. It will be scanned later
4334 * and re-added like an update.
4336 if (pkg.mVersionCode < ps.versionCode) {
4337 shouldHideSystemApp = true;
4338 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
4339 + " but new version " + pkg.mVersionCode + " better than installed "
4340 + ps.versionCode + "; hiding system");
4343 * The newly found system app is a newer version that the
4344 * one previously installed. Simply remove the
4345 * already-installed application and replace it with our own
4346 * while keeping the application data.
4348 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4349 + " reverting from " + ps.codePathString + ": new version "
4350 + pkg.mVersionCode + " better than installed " + ps.versionCode);
4351 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4352 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4353 getAppDexInstructionSets(ps));
4354 synchronized (mInstallLock) {
4355 args.cleanUpResourcesLI();
4361 // The apk is forward locked (not public) if its code and resources
4362 // are kept in different files. (except for app in either system or
4364 // TODO grab this value from PackageSettings
4365 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4366 if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
4367 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
4371 // TODO: extend to support forward-locked splits
4372 String resourcePath = null;
4373 String baseResourcePath = null;
4374 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
4375 if (ps != null && ps.resourcePathString != null) {
4376 resourcePath = ps.resourcePathString;
4377 baseResourcePath = ps.resourcePathString;
4379 // Should not happen at all. Just log an error.
4380 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
4383 resourcePath = pkg.codePath;
4384 baseResourcePath = pkg.baseCodePath;
4387 // Set application objects path explicitly.
4388 pkg.applicationInfo.setCodePath(pkg.codePath);
4389 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
4390 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
4391 pkg.applicationInfo.setResourcePath(resourcePath);
4392 pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
4393 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
4395 // Note that we invoke the following method only if we are about to unpack an application
4396 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
4397 | SCAN_UPDATE_SIGNATURE, currentTime, user);
4400 * If the system app should be overridden by a previously installed
4401 * data, hide the system app now and let the /data/app scan pick it up
4404 if (shouldHideSystemApp) {
4405 synchronized (mPackages) {
4407 * We have to grant systems permissions before we hide, because
4408 * grantPermissions will assume the package update is trying to
4409 * expand its permissions.
4411 grantPermissionsLPw(pkg, true, pkg.packageName);
4412 mSettings.disableSystemPackageLPw(pkg.packageName);
4419 private static String fixProcessName(String defProcessName,
4420 String processName, int uid) {
4421 if (processName == null) {
4422 return defProcessName;
4427 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
4428 throws PackageManagerException {
4429 if (pkgSetting.signatures.mSignatures != null) {
4430 // Already existing package. Make sure signatures match
4431 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
4432 == PackageManager.SIGNATURE_MATCH;
4434 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
4435 == PackageManager.SIGNATURE_MATCH;
4438 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
4439 + pkg.packageName + " signatures do not match the "
4440 + "previously installed version; ignoring!");
4444 // Check for shared user signatures
4445 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
4446 // Already existing package. Make sure signatures match
4447 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4448 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
4450 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
4451 == PackageManager.SIGNATURE_MATCH;
4454 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
4455 "Package " + pkg.packageName
4456 + " has no signatures that match those in shared user "
4457 + pkgSetting.sharedUser.name + "; ignoring!");
4463 * Enforces that only the system UID or root's UID can call a method exposed
4466 * @param message used as message if SecurityException is thrown
4467 * @throws SecurityException if the caller is not system or root
4469 private static final void enforceSystemOrRoot(String message) {
4470 final int uid = Binder.getCallingUid();
4471 if (uid != Process.SYSTEM_UID && uid != 0) {
4472 throw new SecurityException(message);
4477 public void performBootDexOpt() {
4478 enforceSystemOrRoot("Only the system can request dexopt be performed");
4480 final ArraySet<PackageParser.Package> pkgs;
4481 synchronized (mPackages) {
4482 pkgs = mDeferredDexOpt;
4483 mDeferredDexOpt = null;
4487 // Sort apps by importance for dexopt ordering. Important apps are given more priority
4488 // in case the device runs out of space.
4489 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
4490 // Give priority to core apps.
4491 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4492 PackageParser.Package pkg = it.next();
4495 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
4497 sortedPkgs.add(pkg);
4501 // Give priority to system apps that listen for pre boot complete.
4502 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
4503 ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
4504 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4505 PackageParser.Package pkg = it.next();
4506 if (pkgNames.contains(pkg.packageName)) {
4508 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
4510 sortedPkgs.add(pkg);
4514 // Give priority to system apps.
4515 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4516 PackageParser.Package pkg = it.next();
4517 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4519 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
4521 sortedPkgs.add(pkg);
4525 // Give priority to updated system apps.
4526 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4527 PackageParser.Package pkg = it.next();
4528 if (isUpdatedSystemApp(pkg)) {
4530 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
4532 sortedPkgs.add(pkg);
4536 // Give priority to apps that listen for boot complete.
4537 intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
4538 pkgNames = getPackageNamesForIntent(intent);
4539 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4540 PackageParser.Package pkg = it.next();
4541 if (pkgNames.contains(pkg.packageName)) {
4543 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
4545 sortedPkgs.add(pkg);
4549 // Filter out packages that aren't recently used.
4550 filterRecentlyUsedApps(pkgs);
4551 // Add all remaining apps.
4552 for (PackageParser.Package pkg : pkgs) {
4554 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
4556 sortedPkgs.add(pkg);
4559 // If we want to be lazy, filter everything that wasn't recently used.
4561 filterRecentlyUsedApps(sortedPkgs);
4565 int total = sortedPkgs.size();
4566 File dataDir = Environment.getDataDirectory();
4567 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
4568 if (lowThreshold == 0) {
4569 throw new IllegalStateException("Invalid low memory threshold");
4571 for (PackageParser.Package pkg : sortedPkgs) {
4572 long usableSpace = dataDir.getUsableSpace();
4573 if (usableSpace < lowThreshold) {
4574 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
4577 performBootDexOpt(pkg, ++i, total);
4582 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
4583 // Filter out packages that aren't recently used.
4585 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
4586 // should do a full dexopt.
4587 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
4588 int total = pkgs.size();
4590 long now = System.currentTimeMillis();
4591 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
4592 PackageParser.Package pkg = i.next();
4593 long then = pkg.mLastPackageUsageTimeInMills;
4594 if (then + mDexOptLRUThresholdInMills < now) {
4596 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
4597 ((then == 0) ? "never" : new Date(then)));
4604 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
4609 private ArraySet<String> getPackageNamesForIntent(Intent intent) {
4610 List<ResolveInfo> ris = null;
4612 ris = AppGlobals.getPackageManager().queryIntentReceivers(
4613 intent, null, 0, UserHandle.USER_OWNER);
4614 } catch (RemoteException e) {
4616 ArraySet<String> pkgNames = new ArraySet<String>();
4618 for (ResolveInfo ri : ris) {
4619 pkgNames.add(ri.activityInfo.packageName);
4625 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
4627 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
4629 if (!isFirstBoot()) {
4631 ActivityManagerNative.getDefault().showBootMessage(
4632 mContext.getResources().getString(R.string.android_upgrading_apk,
4633 curr, total), true);
4634 } catch (RemoteException e) {
4637 PackageParser.Package p = pkg;
4638 synchronized (mInstallLock) {
4639 performDexOptLI(p, null /* instruction sets */, false /* force dex */,
4640 false /* defer */, true /* include dependencies */);
4645 public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
4646 return performDexOpt(packageName, instructionSet, false);
4649 private static String getPrimaryInstructionSet(ApplicationInfo info) {
4650 if (info.primaryCpuAbi == null) {
4651 return getPreferredInstructionSet();
4654 return VMRuntime.getInstructionSet(info.primaryCpuAbi);
4657 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
4658 boolean dexopt = mLazyDexOpt || backgroundDexopt;
4659 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt
4660 if (!dexopt && !updateUsage) {
4661 // We aren't going to dexopt or update usage, so bail early.
4664 PackageParser.Package p;
4665 final String targetInstructionSet;
4666 synchronized (mPackages) {
4667 p = mPackages.get(packageName);
4672 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
4674 mPackageUsage.write(false);
4676 // We aren't going to dexopt, so bail early.
4680 targetInstructionSet = instructionSet != null ? instructionSet :
4681 getPrimaryInstructionSet(p.applicationInfo);
4682 if (p.mDexOptPerformed.contains(targetInstructionSet)) {
4687 synchronized (mInstallLock) {
4688 final String[] instructionSets = new String[] { targetInstructionSet };
4689 return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
4690 true /* include dependencies */) == DEX_OPT_PERFORMED;
4694 public ArraySet<String> getPackagesThatNeedDexOpt() {
4695 ArraySet<String> pkgs = null;
4696 synchronized (mPackages) {
4697 for (PackageParser.Package p : mPackages.values()) {
4699 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
4701 if (!p.mDexOptPerformed.isEmpty()) {
4705 pkgs = new ArraySet<String>();
4707 pkgs.add(p.packageName);
4713 public void shutdown() {
4714 mPackageUsage.write(true);
4717 private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
4718 boolean forceDex, boolean defer, ArraySet<String> done) {
4719 for (int i=0; i<libs.size(); i++) {
4720 PackageParser.Package libPkg;
4722 synchronized (mPackages) {
4723 libName = libs.get(i);
4724 SharedLibraryEntry lib = mSharedLibraries.get(libName);
4725 if (lib != null && lib.apk != null) {
4726 libPkg = mPackages.get(lib.apk);
4731 if (libPkg != null && !done.contains(libName)) {
4732 performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
4737 static final int DEX_OPT_SKIPPED = 0;
4738 static final int DEX_OPT_PERFORMED = 1;
4739 static final int DEX_OPT_DEFERRED = 2;
4740 static final int DEX_OPT_FAILED = -1;
4742 private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
4743 boolean forceDex, boolean defer, ArraySet<String> done) {
4744 final String[] instructionSets = targetInstructionSets != null ?
4745 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
4748 done.add(pkg.packageName);
4749 if (pkg.usesLibraries != null) {
4750 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
4752 if (pkg.usesOptionalLibraries != null) {
4753 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
4757 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
4758 return DEX_OPT_SKIPPED;
4761 final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
4763 final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
4764 boolean performedDexOpt = false;
4765 // There are three basic cases here:
4766 // 1.) we need to dexopt, either because we are forced or it is needed
4767 // 2.) we are defering a needed dexopt
4768 // 3.) we are skipping an unneeded dexopt
4769 final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
4770 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4771 if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
4775 for (String path : paths) {
4777 // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
4778 // patckage or the one we find does not match the image checksum (i.e. it was
4779 // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
4780 // odex file and it matches the checksum of the image but not its base address,
4781 // meaning we need to move it.
4782 final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
4783 pkg.packageName, dexCodeInstructionSet, defer);
4784 if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
4785 Log.i(TAG, "Running dexopt on: " + path + " pkg="
4786 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
4787 + " vmSafeMode=" + vmSafeMode);
4788 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4789 final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
4790 pkg.packageName, dexCodeInstructionSet, vmSafeMode);
4793 // Don't bother running dexopt again if we failed, it will probably
4794 // just result in an error again. Also, don't bother dexopting for other
4796 return DEX_OPT_FAILED;
4799 performedDexOpt = true;
4800 } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
4801 Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
4802 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4803 final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
4804 pkg.packageName, dexCodeInstructionSet);
4807 // Don't bother running patchoat again if we failed, it will probably
4808 // just result in an error again. Also, don't bother dexopting for other
4810 return DEX_OPT_FAILED;
4813 performedDexOpt = true;
4816 // We're deciding to defer a needed dexopt. Don't bother dexopting for other
4817 // paths and instruction sets. We'll deal with them all together when we process
4818 // our list of deferred dexopts.
4819 if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
4820 if (mDeferredDexOpt == null) {
4821 mDeferredDexOpt = new ArraySet<PackageParser.Package>();
4823 mDeferredDexOpt.add(pkg);
4824 return DEX_OPT_DEFERRED;
4826 } catch (FileNotFoundException e) {
4827 Slog.w(TAG, "Apk not found for dexopt: " + path);
4828 return DEX_OPT_FAILED;
4829 } catch (IOException e) {
4830 Slog.w(TAG, "IOException reading apk: " + path, e);
4831 return DEX_OPT_FAILED;
4832 } catch (StaleDexCacheError e) {
4833 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
4834 return DEX_OPT_FAILED;
4835 } catch (Exception e) {
4836 Slog.w(TAG, "Exception when doing dexopt : ", e);
4837 return DEX_OPT_FAILED;
4841 // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
4842 // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
4843 // it isn't required. We therefore mark that this package doesn't need dexopt unless
4844 // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
4846 pkg.mDexOptPerformed.add(dexCodeInstructionSet);
4849 // If we've gotten here, we're sure that no error occurred and that we haven't
4850 // deferred dex-opt. We've either dex-opted one more paths or instruction sets or
4851 // we've skipped all of them because they are up to date. In both cases this
4852 // package doesn't need dexopt any longer.
4853 return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
4856 private static String[] getAppDexInstructionSets(ApplicationInfo info) {
4857 if (info.primaryCpuAbi != null) {
4858 if (info.secondaryCpuAbi != null) {
4859 return new String[] {
4860 VMRuntime.getInstructionSet(info.primaryCpuAbi),
4861 VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
4863 return new String[] {
4864 VMRuntime.getInstructionSet(info.primaryCpuAbi) };
4868 return new String[] { getPreferredInstructionSet() };
4871 private static String[] getAppDexInstructionSets(PackageSetting ps) {
4872 if (ps.primaryCpuAbiString != null) {
4873 if (ps.secondaryCpuAbiString != null) {
4874 return new String[] {
4875 VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
4876 VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
4878 return new String[] {
4879 VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
4883 return new String[] { getPreferredInstructionSet() };
4886 private static String getPreferredInstructionSet() {
4887 if (sPreferredInstructionSet == null) {
4888 sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
4891 return sPreferredInstructionSet;
4894 private static List<String> getAllInstructionSets() {
4895 final String[] allAbis = Build.SUPPORTED_ABIS;
4896 final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
4898 for (String abi : allAbis) {
4899 final String instructionSet = VMRuntime.getInstructionSet(abi);
4900 if (!allInstructionSets.contains(instructionSet)) {
4901 allInstructionSets.add(instructionSet);
4905 return allInstructionSets;
4909 * Returns the instruction set that should be used to compile dex code. In the presence of
4910 * a native bridge this might be different than the one shared libraries use.
4912 private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
4913 String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
4914 return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
4917 private static String[] getDexCodeInstructionSets(String[] instructionSets) {
4918 ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length);
4919 for (String instructionSet : instructionSets) {
4920 dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
4922 return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
4926 * Returns deduplicated list of supported instructions for dex code.
4928 public static String[] getAllDexCodeInstructionSets() {
4929 String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
4930 for (int i = 0; i < supportedInstructionSets.length; i++) {
4931 String abi = Build.SUPPORTED_ABIS[i];
4932 supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
4934 return getDexCodeInstructionSets(supportedInstructionSets);
4938 public void forceDexOpt(String packageName) {
4939 enforceSystemOrRoot("forceDexOpt");
4941 PackageParser.Package pkg;
4942 synchronized (mPackages) {
4943 pkg = mPackages.get(packageName);
4945 throw new IllegalArgumentException("Missing package: " + packageName);
4949 synchronized (mInstallLock) {
4950 final String[] instructionSets = new String[] {
4951 getPrimaryInstructionSet(pkg.applicationInfo) };
4952 final int res = performDexOptLI(pkg, instructionSets, true, false, true);
4953 if (res != DEX_OPT_PERFORMED) {
4954 throw new IllegalStateException("Failed to dexopt: " + res);
4959 private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets,
4960 boolean forceDex, boolean defer, boolean inclDependencies) {
4961 ArraySet<String> done;
4962 if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
4963 done = new ArraySet<String>();
4964 done.add(pkg.packageName);
4968 return performDexOptLI(pkg, instructionSets, forceDex, defer, done);
4971 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
4972 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
4973 Slog.w(TAG, "Unable to update from " + oldPkg.name
4974 + " to " + newPkg.packageName
4975 + ": old package not in system partition");
4977 } else if (mPackages.get(oldPkg.name) != null) {
4978 Slog.w(TAG, "Unable to update from " + oldPkg.name
4979 + " to " + newPkg.packageName
4980 + ": old package still exists");
4986 File getDataPathForUser(int userId) {
4987 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
4990 private File getDataPathForPackage(String packageName, int userId) {
4992 * Until we fully support multiple users, return the directory we
4993 * previously would have. The PackageManagerTests will need to be
4994 * revised when this is changed back..
4997 return new File(mAppDataDir, packageName);
4999 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
5000 + File.separator + packageName);
5004 private int createDataDirsLI(String packageName, int uid, String seinfo) {
5005 int[] users = sUserManager.getUserIds();
5006 int res = mInstaller.install(packageName, uid, uid, seinfo);
5010 for (int user : users) {
5012 res = mInstaller.createUserData(packageName,
5013 UserHandle.getUid(user, uid), user, seinfo);
5022 private int removeDataDirsLI(String packageName) {
5023 int[] users = sUserManager.getUserIds();
5025 for (int user : users) {
5026 int resInner = mInstaller.remove(packageName, user);
5035 private int deleteCodeCacheDirsLI(String packageName) {
5036 int[] users = sUserManager.getUserIds();
5038 for (int user : users) {
5039 int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
5047 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
5048 PackageParser.Package changingLib) {
5049 if (file.path != null) {
5050 usesLibraryFiles.add(file.path);
5053 PackageParser.Package p = mPackages.get(file.apk);
5054 if (changingLib != null && changingLib.packageName.equals(file.apk)) {
5055 // If we are doing this while in the middle of updating a library apk,
5056 // then we need to make sure to use that new apk for determining the
5057 // dependencies here. (We haven't yet finished committing the new apk
5058 // to the package manager state.)
5059 if (p == null || p.packageName.equals(changingLib.packageName)) {
5064 usesLibraryFiles.addAll(p.getAllCodePaths());
5068 private void updateSharedLibrariesLPw(PackageParser.Package pkg,
5069 PackageParser.Package changingLib) throws PackageManagerException {
5070 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
5071 final ArraySet<String> usesLibraryFiles = new ArraySet<>();
5072 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
5073 for (int i=0; i<N; i++) {
5074 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
5076 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
5077 "Package " + pkg.packageName + " requires unavailable shared library "
5078 + pkg.usesLibraries.get(i) + "; failing!");
5080 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5082 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
5083 for (int i=0; i<N; i++) {
5084 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
5086 Slog.w(TAG, "Package " + pkg.packageName
5087 + " desires unavailable shared library "
5088 + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
5090 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5093 N = usesLibraryFiles.size();
5095 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
5097 pkg.usesLibraryFiles = null;
5102 private static boolean hasString(List<String> list, List<String> which) {
5106 for (int i=list.size()-1; i>=0; i--) {
5107 for (int j=which.size()-1; j>=0; j--) {
5108 if (which.get(j).equals(list.get(i))) {
5116 private void updateAllSharedLibrariesLPw() {
5117 for (PackageParser.Package pkg : mPackages.values()) {
5119 updateSharedLibrariesLPw(pkg, null);
5120 } catch (PackageManagerException e) {
5121 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5126 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
5127 PackageParser.Package changingPkg) {
5128 ArrayList<PackageParser.Package> res = null;
5129 for (PackageParser.Package pkg : mPackages.values()) {
5130 if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
5131 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
5133 res = new ArrayList<PackageParser.Package>();
5137 updateSharedLibrariesLPw(pkg, changingPkg);
5138 } catch (PackageManagerException e) {
5139 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5147 * Derive the value of the {@code cpuAbiOverride} based on the provided
5148 * value and an optional stored value from the package settings.
5150 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
5151 String cpuAbiOverride = null;
5153 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
5154 cpuAbiOverride = null;
5155 } else if (abiOverride != null) {
5156 cpuAbiOverride = abiOverride;
5157 } else if (settings != null) {
5158 cpuAbiOverride = settings.cpuAbiOverrideString;
5161 return cpuAbiOverride;
5164 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
5165 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5166 boolean success = false;
5168 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
5173 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5174 removeDataDirsLI(pkg.packageName);
5179 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
5180 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5181 final File scanFile = new File(pkg.codePath);
5182 if (pkg.applicationInfo.getCodePath() == null ||
5183 pkg.applicationInfo.getResourcePath() == null) {
5184 // Bail out. The resource and code paths haven't been set.
5185 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
5186 "Code and resource paths haven't been set correctly");
5189 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5190 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
5192 // Only allow system apps to be flagged as core apps.
5193 pkg.coreApp = false;
5196 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
5197 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
5200 if (mCustomResolverComponentName != null &&
5201 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
5202 setUpCustomResolverActivity(pkg);
5205 if (pkg.packageName.equals("android")) {
5206 synchronized (mPackages) {
5207 if (mAndroidApplication != null) {
5208 Slog.w(TAG, "*************************************************");
5209 Slog.w(TAG, "Core android package being redefined. Skipping.");
5210 Slog.w(TAG, " file=" + scanFile);
5211 Slog.w(TAG, "*************************************************");
5212 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5213 "Core android package being redefined. Skipping.");
5216 // Set up information for our fall-back user intent resolution activity.
5217 mPlatformPackage = pkg;
5218 pkg.mVersionCode = mSdkVersion;
5219 mAndroidApplication = pkg.applicationInfo;
5221 if (!mResolverReplaced) {
5222 mResolveActivity.applicationInfo = mAndroidApplication;
5223 mResolveActivity.name = ResolverActivity.class.getName();
5224 mResolveActivity.packageName = mAndroidApplication.packageName;
5225 mResolveActivity.processName = "system:ui";
5226 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5227 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
5228 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
5229 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
5230 mResolveActivity.exported = true;
5231 mResolveActivity.enabled = true;
5232 mResolveInfo.activityInfo = mResolveActivity;
5233 mResolveInfo.priority = 0;
5234 mResolveInfo.preferredOrder = 0;
5235 mResolveInfo.match = 0;
5236 mResolveComponentName = new ComponentName(
5237 mAndroidApplication.packageName, mResolveActivity.name);
5242 if (DEBUG_PACKAGE_SCANNING) {
5243 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5244 Log.d(TAG, "Scanning package " + pkg.packageName);
5247 if (mPackages.containsKey(pkg.packageName)
5248 || mSharedLibraries.containsKey(pkg.packageName)) {
5249 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5250 "Application package " + pkg.packageName
5251 + " already installed. Skipping duplicate.");
5254 // Initialize package source and resource directories
5255 File destCodeFile = new File(pkg.applicationInfo.getCodePath());
5256 File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
5258 SharedUserSetting suid = null;
5259 PackageSetting pkgSetting = null;
5261 if (!isSystemApp(pkg)) {
5262 // Only system apps can use these features.
5263 pkg.mOriginalPackages = null;
5264 pkg.mRealPackage = null;
5265 pkg.mAdoptPermissions = null;
5269 synchronized (mPackages) {
5270 if (pkg.mSharedUserId != null) {
5271 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
5273 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5274 "Creating application package " + pkg.packageName
5275 + " for shared user failed");
5277 if (DEBUG_PACKAGE_SCANNING) {
5278 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5279 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
5280 + "): packages=" + suid.packages);
5284 // Check if we are renaming from an original package name.
5285 PackageSetting origPackage = null;
5286 String realName = null;
5287 if (pkg.mOriginalPackages != null) {
5288 // This package may need to be renamed to a previously
5289 // installed name. Let's check on that...
5290 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
5291 if (pkg.mOriginalPackages.contains(renamed)) {
5292 // This package had originally been installed as the
5293 // original name, and we have already taken care of
5294 // transitioning to the new one. Just update the new
5295 // one to continue using the old name.
5296 realName = pkg.mRealPackage;
5297 if (!pkg.packageName.equals(renamed)) {
5298 // Callers into this function may have already taken
5299 // care of renaming the package; only do it here if
5300 // it is not already done.
5301 pkg.setPackageName(renamed);
5305 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
5306 if ((origPackage = mSettings.peekPackageLPr(
5307 pkg.mOriginalPackages.get(i))) != null) {
5308 // We do have the package already installed under its
5309 // original name... should we use it?
5310 if (!verifyPackageUpdateLPr(origPackage, pkg)) {
5311 // New package is not compatible with original.
5314 } else if (origPackage.sharedUser != null) {
5315 // Make sure uid is compatible between packages.
5316 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
5317 Slog.w(TAG, "Unable to migrate data from " + origPackage.name
5318 + " to " + pkg.packageName + ": old uid "
5319 + origPackage.sharedUser.name
5320 + " differs from " + pkg.mSharedUserId);
5325 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
5326 + pkg.packageName + " to old name " + origPackage.name);
5334 if (mTransferedPackages.contains(pkg.packageName)) {
5335 Slog.w(TAG, "Package " + pkg.packageName
5336 + " was transferred to another, but its .apk remains");
5339 // Just create the setting, don't add it yet. For already existing packages
5340 // the PkgSetting exists already and doesn't have to be created.
5341 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
5342 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
5343 pkg.applicationInfo.primaryCpuAbi,
5344 pkg.applicationInfo.secondaryCpuAbi,
5345 pkg.applicationInfo.flags, user, false);
5346 if (pkgSetting == null) {
5347 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5348 "Creating application package " + pkg.packageName + " failed");
5351 if (pkgSetting.origPackage != null) {
5352 // If we are first transitioning from an original package,
5353 // fix up the new package's name now. We need to do this after
5354 // looking up the package under its new name, so getPackageLP
5355 // can take care of fiddling things correctly.
5356 pkg.setPackageName(origPackage.name);
5358 // File a report about this.
5359 String msg = "New package " + pkgSetting.realName
5360 + " renamed to replace old package " + pkgSetting.name;
5361 reportSettingsProblem(Log.WARN, msg);
5363 // Make a note of it.
5364 mTransferedPackages.add(origPackage.name);
5366 // No longer need to retain this.
5367 pkgSetting.origPackage = null;
5370 if (realName != null) {
5371 // Make a note of it.
5372 mTransferedPackages.add(pkg.packageName);
5375 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
5376 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
5379 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5380 // Check all shared libraries and map to their actual file path.
5381 // We only do this here for apps not on a system dir, because those
5382 // are the only ones that can fail an install due to this. We
5383 // will take care of the system apps by updating all of their
5384 // library paths after the scan is done.
5385 updateSharedLibrariesLPw(pkg, null);
5388 if (mFoundPolicyFile) {
5389 SELinuxMMAC.assignSeinfoValue(pkg);
5392 pkg.applicationInfo.uid = pkgSetting.appId;
5393 pkg.mExtras = pkgSetting;
5394 if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
5396 verifySignaturesLP(pkgSetting, pkg);
5397 } catch (PackageManagerException e) {
5398 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5401 // The signature has changed, but this package is in the system
5402 // image... let's recover!
5403 pkgSetting.signatures.mSignatures = pkg.mSignatures;
5404 // However... if this package is part of a shared user, but it
5405 // doesn't match the signature of the shared user, let's fail.
5406 // What this means is that you can't change the signatures
5407 // associated with an overall shared user, which doesn't seem all
5408 // that unreasonable.
5409 if (pkgSetting.sharedUser != null) {
5410 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5411 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
5412 throw new PackageManagerException(
5413 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
5414 "Signature mismatch for shared user : "
5415 + pkgSetting.sharedUser);
5418 // File a report about this.
5419 String msg = "System package " + pkg.packageName
5420 + " signature changed; retaining data.";
5421 reportSettingsProblem(Log.WARN, msg);
5424 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
5425 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5426 + pkg.packageName + " upgrade keys do not match the "
5427 + "previously installed version");
5429 // signatures may have changed as result of upgrade
5430 pkgSetting.signatures.mSignatures = pkg.mSignatures;
5433 // Verify that this new package doesn't have any content providers
5434 // that conflict with existing packages. Only do this if the
5435 // package isn't already installed, since we don't want to break
5436 // things that are installed.
5437 if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
5438 final int N = pkg.providers.size();
5440 for (i=0; i<N; i++) {
5441 PackageParser.Provider p = pkg.providers.get(i);
5442 if (p.info.authority != null) {
5443 String names[] = p.info.authority.split(";");
5444 for (int j = 0; j < names.length; j++) {
5445 if (mProvidersByAuthority.containsKey(names[j])) {
5446 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
5447 final String otherPackageName =
5448 ((other != null && other.getComponentName() != null) ?
5449 other.getComponentName().getPackageName() : "?");
5450 throw new PackageManagerException(
5451 INSTALL_FAILED_CONFLICTING_PROVIDER,
5452 "Can't install because provider name " + names[j]
5453 + " (in package " + pkg.applicationInfo.packageName
5454 + ") is already used by " + otherPackageName);
5461 if (pkg.mAdoptPermissions != null) {
5462 // This package wants to adopt ownership of permissions from
5464 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
5465 final String origName = pkg.mAdoptPermissions.get(i);
5466 final PackageSetting orig = mSettings.peekPackageLPr(origName);
5468 if (verifyPackageUpdateLPr(orig, pkg)) {
5469 Slog.i(TAG, "Adopting permissions from " + origName + " to "
5471 mSettings.transferPermissionsLPw(origName, pkg.packageName);
5478 final String pkgName = pkg.packageName;
5480 final long scanFileTime = scanFile.lastModified();
5481 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
5482 pkg.applicationInfo.processName = fixProcessName(
5483 pkg.applicationInfo.packageName,
5484 pkg.applicationInfo.processName,
5485 pkg.applicationInfo.uid);
5488 if (mPlatformPackage == pkg) {
5489 // The system package is special.
5490 dataPath = new File(Environment.getDataDirectory(), "system");
5492 pkg.applicationInfo.dataDir = dataPath.getPath();
5495 // This is a normal package, need to make its data directory.
5496 dataPath = getDataPathForPackage(pkg.packageName, 0);
5498 boolean uidError = false;
5499 if (dataPath.exists()) {
5502 StructStat stat = Os.stat(dataPath.getPath());
5503 currentUid = stat.st_uid;
5504 } catch (ErrnoException e) {
5505 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
5508 // If we have mismatched owners for the data path, we have a problem.
5509 if (currentUid != pkg.applicationInfo.uid) {
5510 boolean recovered = false;
5511 if (currentUid == 0) {
5512 // The directory somehow became owned by root. Wow.
5513 // This is probably because the system was stopped while
5514 // installd was in the middle of messing with its libs
5515 // directory. Ask installd to fix that.
5516 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
5517 pkg.applicationInfo.uid);
5520 String msg = "Package " + pkg.packageName
5521 + " unexpectedly changed to uid 0; recovered to " +
5522 + pkg.applicationInfo.uid;
5523 reportSettingsProblem(Log.WARN, msg);
5526 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5527 || (scanFlags&SCAN_BOOTING) != 0)) {
5528 // If this is a system app, we can at least delete its
5529 // current data so the application will still work.
5530 int ret = removeDataDirsLI(pkgName);
5532 // TODO: Kill the processes first
5534 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5535 ? "System package " : "Third party package ";
5536 String msg = prefix + pkg.packageName
5537 + " has changed from uid: "
5538 + currentUid + " to "
5539 + pkg.applicationInfo.uid + "; old data erased";
5540 reportSettingsProblem(Log.WARN, msg);
5543 // And now re-install the app.
5544 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5545 pkg.applicationInfo.seinfo);
5547 // Ack should not happen!
5548 msg = prefix + pkg.packageName
5549 + " could not have data directory re-created after delete.";
5550 reportSettingsProblem(Log.WARN, msg);
5551 throw new PackageManagerException(
5552 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
5556 mHasSystemUidErrors = true;
5558 } else if (!recovered) {
5559 // If we allow this install to proceed, we will be broken.
5561 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
5565 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
5566 + pkg.applicationInfo.uid + "/fs_"
5568 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
5569 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
5570 String msg = "Package " + pkg.packageName
5571 + " has mismatched uid: "
5572 + currentUid + " on disk, "
5573 + pkg.applicationInfo.uid + " in settings";
5575 synchronized (mPackages) {
5576 mSettings.mReadMessages.append(msg);
5577 mSettings.mReadMessages.append('\n');
5579 if (!pkgSetting.uidError) {
5580 reportSettingsProblem(Log.ERROR, msg);
5585 pkg.applicationInfo.dataDir = dataPath.getPath();
5586 if (mShouldRestoreconData) {
5587 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
5588 mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
5589 pkg.applicationInfo.uid);
5592 if (DEBUG_PACKAGE_SCANNING) {
5593 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5594 Log.v(TAG, "Want this data dir: " + dataPath);
5596 //invoke installer to do the actual installation
5597 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5598 pkg.applicationInfo.seinfo);
5600 // Error from installer
5601 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5602 "Unable to create data dirs [errorCode=" + ret + "]");
5605 if (dataPath.exists()) {
5606 pkg.applicationInfo.dataDir = dataPath.getPath();
5608 Slog.w(TAG, "Unable to create data directory: " + dataPath);
5609 pkg.applicationInfo.dataDir = null;
5613 pkgSetting.uidError = uidError;
5616 final String path = scanFile.getPath();
5617 final String codePath = pkg.applicationInfo.getCodePath();
5618 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
5619 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
5620 setBundledAppAbisAndRoots(pkg, pkgSetting);
5622 // If we haven't found any native libraries for the app, check if it has
5623 // renderscript code. We'll need to force the app to 32 bit if it has
5624 // renderscript bitcode.
5625 if (pkg.applicationInfo.primaryCpuAbi == null
5626 && pkg.applicationInfo.secondaryCpuAbi == null
5627 && Build.SUPPORTED_64_BIT_ABIS.length > 0) {
5628 NativeLibraryHelper.Handle handle = null;
5630 handle = NativeLibraryHelper.Handle.create(scanFile);
5631 if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5632 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
5634 } catch (IOException ioe) {
5635 Slog.w(TAG, "Error scanning system app : " + ioe);
5637 IoUtils.closeQuietly(handle);
5641 setNativeLibraryPaths(pkg);
5643 // TODO: We can probably be smarter about this stuff. For installed apps,
5644 // we can calculate this information at install time once and for all. For
5645 // system apps, we can probably assume that this information doesn't change
5646 // after the first boot scan. As things stand, we do lots of unnecessary work.
5648 // Give ourselves some initial paths; we'll come back for another
5649 // pass once we've determined ABI below.
5650 setNativeLibraryPaths(pkg);
5652 final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
5653 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
5654 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
5656 NativeLibraryHelper.Handle handle = null;
5658 handle = NativeLibraryHelper.Handle.create(scanFile);
5659 // TODO(multiArch): This can be null for apps that didn't go through the
5660 // usual installation process. We can calculate it again, like we
5661 // do during install time.
5663 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
5665 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
5667 // Null out the abis so that they can be recalculated.
5668 pkg.applicationInfo.primaryCpuAbi = null;
5669 pkg.applicationInfo.secondaryCpuAbi = null;
5670 if (isMultiArch(pkg.applicationInfo)) {
5671 // Warn if we've set an abiOverride for multi-lib packages..
5672 // By definition, we need to copy both 32 and 64 bit libraries for
5674 if (pkg.cpuAbiOverride != null
5675 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
5676 Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
5679 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
5680 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
5681 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
5683 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
5685 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5686 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
5687 useIsaSpecificSubdirs);
5691 maybeThrowExceptionForMultiArchCopy(
5692 "Error unpackaging 32 bit native libs for multiarch app.", abi32);
5694 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
5696 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
5698 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5699 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
5700 useIsaSpecificSubdirs);
5704 maybeThrowExceptionForMultiArchCopy(
5705 "Error unpackaging 64 bit native libs for multiarch app.", abi64);
5708 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
5712 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
5714 pkg.applicationInfo.secondaryCpuAbi = abi;
5716 pkg.applicationInfo.primaryCpuAbi = abi;
5720 String[] abiList = (cpuAbiOverride != null) ?
5721 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
5723 // Enable gross and lame hacks for apps that are built with old
5724 // SDK tools. We must scan their APKs for renderscript bitcode and
5725 // not launch them if it's present. Don't bother checking on devices
5726 // that don't have 64 bit support.
5727 boolean needsRenderScriptOverride = false;
5728 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
5729 NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5730 abiList = Build.SUPPORTED_32_BIT_ABIS;
5731 needsRenderScriptOverride = true;
5736 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
5738 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5739 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
5742 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
5743 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5744 "Error unpackaging native libs for app, errorCode=" + copyRet);
5748 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
5749 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
5750 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
5751 } else if (needsRenderScriptOverride) {
5752 pkg.applicationInfo.primaryCpuAbi = abiList[0];
5755 } catch (IOException ioe) {
5756 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
5758 IoUtils.closeQuietly(handle);
5761 // Now that we've calculated the ABIs and determined if it's an internal app,
5762 // we will go ahead and populate the nativeLibraryPath.
5763 setNativeLibraryPaths(pkg);
5765 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
5766 final int[] userIds = sUserManager.getUserIds();
5767 synchronized (mInstallLock) {
5768 // Create a native library symlink only if we have native libraries
5769 // and if the native libraries are 32 bit libraries. We do not provide
5770 // this symlink for 64 bit libraries.
5771 if (pkg.applicationInfo.primaryCpuAbi != null &&
5772 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
5773 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
5774 for (int userId : userIds) {
5775 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
5776 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5777 "Failed linking native library dir (user=" + userId + ")");
5784 // This is a special case for the "system" package, where the ABI is
5785 // dictated by the zygote configuration (and init.rc). We should keep track
5786 // of this ABI so that we can deal with "normal" applications that run under
5787 // the same UID correctly.
5788 if (mPlatformPackage == pkg) {
5789 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
5790 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
5793 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
5794 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
5795 pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
5796 // Copy the derived override back to the parsed package, so that we can
5797 // update the package settings accordingly.
5798 pkg.cpuAbiOverride = cpuAbiOverride;
5800 if (DEBUG_ABI_SELECTION) {
5801 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
5802 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
5803 + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
5806 // Push the derived path down into PackageSettings so we know what to
5807 // clean up at uninstall time.
5808 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
5810 if (DEBUG_ABI_SELECTION) {
5811 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
5812 " primary=" + pkg.applicationInfo.primaryCpuAbi +
5813 " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
5816 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
5817 // We don't do this here during boot because we can do it all
5818 // at once after scanning all existing packages.
5820 // We also do this *before* we perform dexopt on this package, so that
5821 // we can avoid redundant dexopts, and also to make sure we've got the
5822 // code and package path correct.
5823 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
5824 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
5827 if ((scanFlags & SCAN_NO_DEX) == 0) {
5828 if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
5829 (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5830 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
5834 if (mFactoryTest && pkg.requestedPermissions.contains(
5835 android.Manifest.permission.FACTORY_TEST)) {
5836 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
5839 ArrayList<PackageParser.Package> clientLibPkgs = null;
5842 synchronized (mPackages) {
5843 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5844 // Only system apps can add new shared libraries.
5845 if (pkg.libraryNames != null) {
5846 for (int i=0; i<pkg.libraryNames.size(); i++) {
5847 String name = pkg.libraryNames.get(i);
5848 boolean allowed = false;
5849 if (isUpdatedSystemApp(pkg)) {
5850 // New library entries can only be added through the
5851 // system image. This is important to get rid of a lot
5852 // of nasty edge cases: for example if we allowed a non-
5853 // system update of the app to add a library, then uninstalling
5854 // the update would make the library go away, and assumptions
5855 // we made such as through app install filtering would now
5856 // have allowed apps on the device which aren't compatible
5857 // with it. Better to just have the restriction here, be
5858 // conservative, and create many fewer cases that can negatively
5859 // impact the user experience.
5860 final PackageSetting sysPs = mSettings
5861 .getDisabledSystemPkgLPr(pkg.packageName);
5862 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
5863 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
5864 if (name.equals(sysPs.pkg.libraryNames.get(j))) {
5875 if (!mSharedLibraries.containsKey(name)) {
5876 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
5877 } else if (!name.equals(pkg.packageName)) {
5878 Slog.w(TAG, "Package " + pkg.packageName + " library "
5879 + name + " already exists; skipping");
5882 Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
5883 + name + " that is not declared on system image; skipping");
5886 if ((scanFlags&SCAN_BOOTING) == 0) {
5887 // If we are not booting, we need to update any applications
5888 // that are clients of our shared library. If we are booting,
5889 // this will all be done once the scan is complete.
5890 clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
5896 // We also need to dexopt any apps that are dependent on this library. Note that
5897 // if these fail, we should abort the install since installing the library will
5898 // result in some apps being broken.
5899 if (clientLibPkgs != null) {
5900 if ((scanFlags & SCAN_NO_DEX) == 0) {
5901 for (int i = 0; i < clientLibPkgs.size(); i++) {
5902 PackageParser.Package clientPkg = clientLibPkgs.get(i);
5903 if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
5904 (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5905 throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
5906 "scanPackageLI failed to dexopt clientLibPkgs");
5912 // Request the ActivityManager to kill the process(only for existing packages)
5913 // so that we do not end up in a confused state while the user is still using the older
5914 // version of the application while the new one gets installed.
5915 if ((scanFlags & SCAN_REPLACING) != 0) {
5916 killApplication(pkg.applicationInfo.packageName,
5917 pkg.applicationInfo.uid, "update pkg");
5920 // Also need to kill any apps that are dependent on the library.
5921 if (clientLibPkgs != null) {
5922 for (int i=0; i<clientLibPkgs.size(); i++) {
5923 PackageParser.Package clientPkg = clientLibPkgs.get(i);
5924 killApplication(clientPkg.applicationInfo.packageName,
5925 clientPkg.applicationInfo.uid, "update lib");
5930 synchronized (mPackages) {
5931 // We don't expect installation to fail beyond this point
5933 // Add the new setting to mSettings
5934 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
5935 // Add the new setting to mPackages
5936 mPackages.put(pkg.applicationInfo.packageName, pkg);
5937 // Make sure we don't accidentally delete its data.
5938 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
5939 while (iter.hasNext()) {
5940 PackageCleanItem item = iter.next();
5941 if (pkgName.equals(item.packageName)) {
5946 // Take care of first install / last update times.
5947 if (currentTime != 0) {
5948 if (pkgSetting.firstInstallTime == 0) {
5949 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
5950 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
5951 pkgSetting.lastUpdateTime = currentTime;
5953 } else if (pkgSetting.firstInstallTime == 0) {
5954 // We need *something*. Take time time stamp of the file.
5955 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
5956 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
5957 if (scanFileTime != pkgSetting.timeStamp) {
5958 // A package on the system image has changed; consider this
5960 pkgSetting.lastUpdateTime = scanFileTime;
5964 // Add the package's KeySets to the global KeySetManagerService
5965 KeySetManagerService ksms = mSettings.mKeySetManagerService;
5967 // Old KeySetData no longer valid.
5968 ksms.removeAppKeySetDataLPw(pkg.packageName);
5969 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
5970 if (pkg.mKeySetMapping != null) {
5971 for (Map.Entry<String, ArraySet<PublicKey>> entry :
5972 pkg.mKeySetMapping.entrySet()) {
5973 if (entry.getValue() != null) {
5974 ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
5975 entry.getValue(), entry.getKey());
5978 if (pkg.mUpgradeKeySets != null) {
5979 for (String upgradeAlias : pkg.mUpgradeKeySets) {
5980 ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
5984 } catch (NullPointerException e) {
5985 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
5986 } catch (IllegalArgumentException e) {
5987 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
5990 int N = pkg.providers.size();
5991 StringBuilder r = null;
5993 for (i=0; i<N; i++) {
5994 PackageParser.Provider p = pkg.providers.get(i);
5995 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
5996 p.info.processName, pkg.applicationInfo.uid);
5997 mProviders.addProvider(p);
5998 p.syncable = p.info.isSyncable;
5999 if (p.info.authority != null) {
6000 String names[] = p.info.authority.split(";");
6001 p.info.authority = null;
6002 for (int j = 0; j < names.length; j++) {
6003 if (j == 1 && p.syncable) {
6004 // We only want the first authority for a provider to possibly be
6005 // syncable, so if we already added this provider using a different
6006 // authority clear the syncable flag. We copy the provider before
6007 // changing it because the mProviders object contains a reference
6008 // to a provider that we don't want to change.
6009 // Only do this for the second authority since the resulting provider
6010 // object can be the same for all future authorities for this provider.
6011 p = new PackageParser.Provider(p);
6014 if (!mProvidersByAuthority.containsKey(names[j])) {
6015 mProvidersByAuthority.put(names[j], p);
6016 if (p.info.authority == null) {
6017 p.info.authority = names[j];
6019 p.info.authority = p.info.authority + ";" + names[j];
6021 if (DEBUG_PACKAGE_SCANNING) {
6022 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6023 Log.d(TAG, "Registered content provider: " + names[j]
6024 + ", className = " + p.info.name + ", isSyncable = "
6025 + p.info.isSyncable);
6028 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6029 Slog.w(TAG, "Skipping provider name " + names[j] +
6030 " (in package " + pkg.applicationInfo.packageName +
6031 "): name already used by "
6032 + ((other != null && other.getComponentName() != null)
6033 ? other.getComponentName().getPackageName() : "?"));
6037 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6039 r = new StringBuilder(256);
6043 r.append(p.info.name);
6047 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
6050 N = pkg.services.size();
6052 for (i=0; i<N; i++) {
6053 PackageParser.Service s = pkg.services.get(i);
6054 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
6055 s.info.processName, pkg.applicationInfo.uid);
6056 mServices.addService(s);
6057 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6059 r = new StringBuilder(256);
6063 r.append(s.info.name);
6067 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
6070 N = pkg.receivers.size();
6072 for (i=0; i<N; i++) {
6073 PackageParser.Activity a = pkg.receivers.get(i);
6074 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6075 a.info.processName, pkg.applicationInfo.uid);
6076 mReceivers.addActivity(a, "receiver");
6077 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6079 r = new StringBuilder(256);
6083 r.append(a.info.name);
6087 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
6090 N = pkg.activities.size();
6092 for (i=0; i<N; i++) {
6093 PackageParser.Activity a = pkg.activities.get(i);
6094 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6095 a.info.processName, pkg.applicationInfo.uid);
6096 mActivities.addActivity(a, "activity");
6097 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6099 r = new StringBuilder(256);
6103 r.append(a.info.name);
6107 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
6110 N = pkg.permissionGroups.size();
6112 for (i=0; i<N; i++) {
6113 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
6114 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
6116 mPermissionGroups.put(pg.info.name, pg);
6117 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6119 r = new StringBuilder(256);
6123 r.append(pg.info.name);
6126 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
6127 + pg.info.packageName + " ignored: original from "
6128 + cur.info.packageName);
6129 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6131 r = new StringBuilder(256);
6136 r.append(pg.info.name);
6141 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r);
6144 N = pkg.permissions.size();
6146 for (i=0; i<N; i++) {
6147 PackageParser.Permission p = pkg.permissions.get(i);
6148 ArrayMap<String, BasePermission> permissionMap =
6149 p.tree ? mSettings.mPermissionTrees
6150 : mSettings.mPermissions;
6151 p.group = mPermissionGroups.get(p.info.group);
6152 if (p.info.group == null || p.group != null) {
6153 BasePermission bp = permissionMap.get(p.info.name);
6155 // Allow system apps to redefine non-system permissions
6156 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
6157 final boolean currentOwnerIsSystem = (bp.perm != null
6158 && isSystemApp(bp.perm.owner));
6159 if (isSystemApp(p.owner)) {
6160 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
6161 // It's a built-in permission and no owner, take ownership now
6162 bp.packageSetting = pkgSetting;
6164 bp.uid = pkg.applicationInfo.uid;
6165 bp.sourcePackage = p.info.packageName;
6166 } else if (!currentOwnerIsSystem) {
6167 String msg = "New decl " + p.owner + " of permission "
6168 + p.info.name + " is system; overriding " + bp.sourcePackage;
6169 reportSettingsProblem(Log.WARN, msg);
6176 bp = new BasePermission(p.info.name, p.info.packageName,
6177 BasePermission.TYPE_NORMAL);
6178 permissionMap.put(p.info.name, bp);
6181 if (bp.perm == null) {
6182 if (bp.sourcePackage == null
6183 || bp.sourcePackage.equals(p.info.packageName)) {
6184 BasePermission tree = findPermissionTreeLP(p.info.name);
6186 || tree.sourcePackage.equals(p.info.packageName)) {
6187 bp.packageSetting = pkgSetting;
6189 bp.uid = pkg.applicationInfo.uid;
6190 bp.sourcePackage = p.info.packageName;
6191 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6193 r = new StringBuilder(256);
6197 r.append(p.info.name);
6200 Slog.w(TAG, "Permission " + p.info.name + " from package "
6201 + p.info.packageName + " ignored: base tree "
6202 + tree.name + " is from package "
6203 + tree.sourcePackage);
6206 Slog.w(TAG, "Permission " + p.info.name + " from package "
6207 + p.info.packageName + " ignored: original from "
6208 + bp.sourcePackage);
6210 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6212 r = new StringBuilder(256);
6217 r.append(p.info.name);
6220 bp.protectionLevel = p.info.protectionLevel;
6223 Slog.w(TAG, "Permission " + p.info.name + " from package "
6224 + p.info.packageName + " ignored: no group "
6229 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
6232 N = pkg.instrumentation.size();
6234 for (i=0; i<N; i++) {
6235 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6236 a.info.packageName = pkg.applicationInfo.packageName;
6237 a.info.sourceDir = pkg.applicationInfo.sourceDir;
6238 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
6239 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
6240 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
6241 a.info.dataDir = pkg.applicationInfo.dataDir;
6243 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
6244 // need other information about the application, like the ABI and what not ?
6245 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
6246 mInstrumentation.put(a.getComponentName(), a);
6247 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6249 r = new StringBuilder(256);
6253 r.append(a.info.name);
6257 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
6260 if (pkg.protectedBroadcasts != null) {
6261 N = pkg.protectedBroadcasts.size();
6262 for (i=0; i<N; i++) {
6263 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
6267 pkgSetting.setTimeStamp(scanFileTime);
6269 // Create idmap files for pairs of (packages, overlay packages).
6270 // Note: "android", ie framework-res.apk, is handled by native layers.
6271 if (pkg.mOverlayTarget != null) {
6272 // This is an overlay package.
6273 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
6274 if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
6275 mOverlays.put(pkg.mOverlayTarget,
6276 new ArrayMap<String, PackageParser.Package>());
6278 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
6279 map.put(pkg.packageName, pkg);
6280 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
6281 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
6282 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6283 "scanPackageLI failed to createIdmap");
6286 } else if (mOverlays.containsKey(pkg.packageName) &&
6287 !pkg.packageName.equals("android")) {
6288 // This is a regular package, with one or more known overlay packages.
6289 createIdmapsForPackageLI(pkg);
6297 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
6298 * i.e, so that all packages can be run inside a single process if required.
6300 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
6301 * this function will either try and make the ABI for all packages in {@code packagesForUser}
6302 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
6303 * the ABI selected for {@code packagesForUser}. This variant is used when installing or
6304 * updating a package that belongs to a shared user.
6306 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
6307 * adds unnecessary complexity.
6309 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
6310 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
6311 String requiredInstructionSet = null;
6312 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
6313 requiredInstructionSet = VMRuntime.getInstructionSet(
6314 scannedPackage.applicationInfo.primaryCpuAbi);
6317 PackageSetting requirer = null;
6318 for (PackageSetting ps : packagesForUser) {
6319 // If packagesForUser contains scannedPackage, we skip it. This will happen
6320 // when scannedPackage is an update of an existing package. Without this check,
6321 // we will never be able to change the ABI of any package belonging to a shared
6322 // user, even if it's compatible with other packages.
6323 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6324 if (ps.primaryCpuAbiString == null) {
6328 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
6329 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
6330 // We have a mismatch between instruction sets (say arm vs arm64) warn about
6331 // this but there's not much we can do.
6332 String errorMessage = "Instruction set mismatch, "
6333 + ((requirer == null) ? "[caller]" : requirer)
6334 + " requires " + requiredInstructionSet + " whereas " + ps
6335 + " requires " + instructionSet;
6336 Slog.w(TAG, errorMessage);
6339 if (requiredInstructionSet == null) {
6340 requiredInstructionSet = instructionSet;
6346 if (requiredInstructionSet != null) {
6348 if (requirer != null) {
6349 // requirer != null implies that either scannedPackage was null or that scannedPackage
6350 // did not require an ABI, in which case we have to adjust scannedPackage to match
6351 // the ABI of the set (which is the same as requirer's ABI)
6352 adjustedAbi = requirer.primaryCpuAbiString;
6353 if (scannedPackage != null) {
6354 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
6357 // requirer == null implies that we're updating all ABIs in the set to
6358 // match scannedPackage.
6359 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
6362 for (PackageSetting ps : packagesForUser) {
6363 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6364 if (ps.primaryCpuAbiString != null) {
6368 ps.primaryCpuAbiString = adjustedAbi;
6369 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
6370 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
6371 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
6373 if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
6374 deferDexOpt, true) == DEX_OPT_FAILED) {
6375 ps.primaryCpuAbiString = null;
6376 ps.pkg.applicationInfo.primaryCpuAbi = null;
6379 mInstaller.rmdex(ps.codePathString,
6380 getDexCodeInstructionSet(getPreferredInstructionSet()));
6388 private void setUpCustomResolverActivity(PackageParser.Package pkg) {
6389 synchronized (mPackages) {
6390 mResolverReplaced = true;
6391 // Set up information for custom user intent resolution activity.
6392 mResolveActivity.applicationInfo = pkg.applicationInfo;
6393 mResolveActivity.name = mCustomResolverComponentName.getClassName();
6394 mResolveActivity.packageName = pkg.applicationInfo.packageName;
6395 mResolveActivity.processName = null;
6396 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6397 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
6398 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
6399 mResolveActivity.theme = 0;
6400 mResolveActivity.exported = true;
6401 mResolveActivity.enabled = true;
6402 mResolveInfo.activityInfo = mResolveActivity;
6403 mResolveInfo.priority = 0;
6404 mResolveInfo.preferredOrder = 0;
6405 mResolveInfo.match = 0;
6406 mResolveComponentName = mCustomResolverComponentName;
6407 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
6408 mResolveComponentName);
6412 private static String calculateBundledApkRoot(final String codePathString) {
6413 final File codePath = new File(codePathString);
6414 final File codeRoot;
6415 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
6416 codeRoot = Environment.getRootDirectory();
6417 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
6418 codeRoot = Environment.getOemDirectory();
6419 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
6420 codeRoot = Environment.getVendorDirectory();
6422 // Unrecognized code path; take its top real segment as the apk root:
6423 // e.g. /something/app/blah.apk => /something
6425 File f = codePath.getCanonicalFile();
6426 File parent = f.getParentFile(); // non-null because codePath is a file
6428 while ((tmp = parent.getParentFile()) != null) {
6433 Slog.w(TAG, "Unrecognized code path "
6434 + codePath + " - using " + codeRoot);
6435 } catch (IOException e) {
6436 // Can't canonicalize the code path -- shenanigans?
6437 Slog.w(TAG, "Can't canonicalize code path " + codePath);
6438 return Environment.getRootDirectory().getPath();
6441 return codeRoot.getPath();
6445 * Derive and set the location of native libraries for the given package,
6446 * which varies depending on where and how the package was installed.
6448 private void setNativeLibraryPaths(PackageParser.Package pkg) {
6449 final ApplicationInfo info = pkg.applicationInfo;
6450 final String codePath = pkg.codePath;
6451 final File codeFile = new File(codePath);
6452 final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
6453 final boolean asecApp = isForwardLocked(info) || isExternal(info);
6455 info.nativeLibraryRootDir = null;
6456 info.nativeLibraryRootRequiresIsa = false;
6457 info.nativeLibraryDir = null;
6458 info.secondaryNativeLibraryDir = null;
6460 if (isApkFile(codeFile)) {
6461 // Monolithic install
6463 // If "/system/lib64/apkname" exists, assume that is the per-package
6464 // native library directory to use; otherwise use "/system/lib/apkname".
6465 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
6466 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
6467 getPrimaryInstructionSet(info));
6469 // This is a bundled system app so choose the path based on the ABI.
6470 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
6471 // is just the default path.
6472 final String apkName = deriveCodePathName(codePath);
6473 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
6474 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
6475 apkName).getAbsolutePath();
6477 if (info.secondaryCpuAbi != null) {
6478 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
6479 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
6480 secondaryLibDir, apkName).getAbsolutePath();
6482 } else if (asecApp) {
6483 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
6486 final String apkName = deriveCodePathName(codePath);
6487 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
6491 info.nativeLibraryRootRequiresIsa = false;
6492 info.nativeLibraryDir = info.nativeLibraryRootDir;
6495 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
6496 info.nativeLibraryRootRequiresIsa = true;
6498 info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
6499 getPrimaryInstructionSet(info)).getAbsolutePath();
6501 if (info.secondaryCpuAbi != null) {
6502 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
6503 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
6509 * Calculate the abis and roots for a bundled app. These can uniquely
6510 * be determined from the contents of the system partition, i.e whether
6511 * it contains 64 or 32 bit shared libraries etc. We do not validate any
6512 * of this information, and instead assume that the system was built
6515 private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
6516 PackageSetting pkgSetting) {
6517 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
6519 // If "/system/lib64/apkname" exists, assume that is the per-package
6520 // native library directory to use; otherwise use "/system/lib/apkname".
6521 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
6522 setBundledAppAbi(pkg, apkRoot, apkName);
6523 // pkgSetting might be null during rescan following uninstall of updates
6524 // to a bundled app, so accommodate that possibility. The settings in
6525 // that case will be established later from the parsed package.
6527 // If the settings aren't null, sync them up with what we've just derived.
6528 // note that apkRoot isn't stored in the package settings.
6529 if (pkgSetting != null) {
6530 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
6531 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
6536 * Deduces the ABI of a bundled app and sets the relevant fields on the
6537 * parsed pkg object.
6539 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
6540 * under which system libraries are installed.
6541 * @param apkName the name of the installed package.
6543 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
6544 final File codeFile = new File(pkg.codePath);
6546 final boolean has64BitLibs;
6547 final boolean has32BitLibs;
6548 if (isApkFile(codeFile)) {
6549 // Monolithic install
6550 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
6551 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
6554 final File rootDir = new File(codeFile, LIB_DIR_NAME);
6555 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
6556 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
6557 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
6558 has64BitLibs = (new File(rootDir, isa)).exists();
6560 has64BitLibs = false;
6562 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
6563 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
6564 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
6565 has32BitLibs = (new File(rootDir, isa)).exists();
6567 has32BitLibs = false;
6571 if (has64BitLibs && !has32BitLibs) {
6572 // The package has 64 bit libs, but not 32 bit libs. Its primary
6573 // ABI should be 64 bit. We can safely assume here that the bundled
6574 // native libraries correspond to the most preferred ABI in the list.
6576 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6577 pkg.applicationInfo.secondaryCpuAbi = null;
6578 } else if (has32BitLibs && !has64BitLibs) {
6579 // The package has 32 bit libs but not 64 bit libs. Its primary
6580 // ABI should be 32 bit.
6582 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6583 pkg.applicationInfo.secondaryCpuAbi = null;
6584 } else if (has32BitLibs && has64BitLibs) {
6585 // The application has both 64 and 32 bit bundled libraries. We check
6586 // here that the app declares multiArch support, and warn if it doesn't.
6588 // We will be lenient here and record both ABIs. The primary will be the
6589 // ABI that's higher on the list, i.e, a device that's configured to prefer
6590 // 64 bit apps will see a 64 bit primary ABI,
6592 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
6593 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
6596 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
6597 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6598 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6600 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6601 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6604 pkg.applicationInfo.primaryCpuAbi = null;
6605 pkg.applicationInfo.secondaryCpuAbi = null;
6609 private void killApplication(String pkgName, int appId, String reason) {
6610 // Request the ActivityManager to kill the process(only for existing packages)
6611 // so that we do not end up in a confused state while the user is still using the older
6612 // version of the application while the new one gets installed.
6613 IActivityManager am = ActivityManagerNative.getDefault();
6616 am.killApplicationWithAppId(pkgName, appId, reason);
6617 } catch (RemoteException e) {
6622 void removePackageLI(PackageSetting ps, boolean chatty) {
6623 if (DEBUG_INSTALL) {
6625 Log.d(TAG, "Removing package " + ps.name);
6629 synchronized (mPackages) {
6630 mPackages.remove(ps.name);
6631 final PackageParser.Package pkg = ps.pkg;
6633 cleanPackageDataStructuresLILPw(pkg, chatty);
6638 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
6639 if (DEBUG_INSTALL) {
6641 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
6645 synchronized (mPackages) {
6646 mPackages.remove(pkg.applicationInfo.packageName);
6647 cleanPackageDataStructuresLILPw(pkg, chatty);
6651 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
6652 int N = pkg.providers.size();
6653 StringBuilder r = null;
6655 for (i=0; i<N; i++) {
6656 PackageParser.Provider p = pkg.providers.get(i);
6657 mProviders.removeProvider(p);
6658 if (p.info.authority == null) {
6660 /* There was another ContentProvider with this authority when
6661 * this app was installed so this authority is null,
6662 * Ignore it as we don't have to unregister the provider.
6666 String names[] = p.info.authority.split(";");
6667 for (int j = 0; j < names.length; j++) {
6668 if (mProvidersByAuthority.get(names[j]) == p) {
6669 mProvidersByAuthority.remove(names[j]);
6672 Log.d(TAG, "Unregistered content provider: " + names[j]
6673 + ", className = " + p.info.name + ", isSyncable = "
6674 + p.info.isSyncable);
6678 if (DEBUG_REMOVE && chatty) {
6680 r = new StringBuilder(256);
6684 r.append(p.info.name);
6688 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
6691 N = pkg.services.size();
6693 for (i=0; i<N; i++) {
6694 PackageParser.Service s = pkg.services.get(i);
6695 mServices.removeService(s);
6698 r = new StringBuilder(256);
6702 r.append(s.info.name);
6706 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
6709 N = pkg.receivers.size();
6711 for (i=0; i<N; i++) {
6712 PackageParser.Activity a = pkg.receivers.get(i);
6713 mReceivers.removeActivity(a, "receiver");
6714 if (DEBUG_REMOVE && chatty) {
6716 r = new StringBuilder(256);
6720 r.append(a.info.name);
6724 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
6727 N = pkg.activities.size();
6729 for (i=0; i<N; i++) {
6730 PackageParser.Activity a = pkg.activities.get(i);
6731 mActivities.removeActivity(a, "activity");
6732 if (DEBUG_REMOVE && chatty) {
6734 r = new StringBuilder(256);
6738 r.append(a.info.name);
6742 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
6745 N = pkg.permissions.size();
6747 for (i=0; i<N; i++) {
6748 PackageParser.Permission p = pkg.permissions.get(i);
6749 BasePermission bp = mSettings.mPermissions.get(p.info.name);
6751 bp = mSettings.mPermissionTrees.get(p.info.name);
6753 if (bp != null && bp.perm == p) {
6755 if (DEBUG_REMOVE && chatty) {
6757 r = new StringBuilder(256);
6761 r.append(p.info.name);
6764 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6765 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
6766 if (appOpPerms != null) {
6767 appOpPerms.remove(pkg.packageName);
6772 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
6775 N = pkg.requestedPermissions.size();
6777 for (i=0; i<N; i++) {
6778 String perm = pkg.requestedPermissions.get(i);
6779 BasePermission bp = mSettings.mPermissions.get(perm);
6780 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6781 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
6782 if (appOpPerms != null) {
6783 appOpPerms.remove(pkg.packageName);
6784 if (appOpPerms.isEmpty()) {
6785 mAppOpPermissionPackages.remove(perm);
6791 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
6794 N = pkg.instrumentation.size();
6796 for (i=0; i<N; i++) {
6797 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6798 mInstrumentation.remove(a.getComponentName());
6799 if (DEBUG_REMOVE && chatty) {
6801 r = new StringBuilder(256);
6805 r.append(a.info.name);
6809 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
6813 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6814 // Only system apps can hold shared libraries.
6815 if (pkg.libraryNames != null) {
6816 for (i=0; i<pkg.libraryNames.size(); i++) {
6817 String name = pkg.libraryNames.get(i);
6818 SharedLibraryEntry cur = mSharedLibraries.get(name);
6819 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
6820 mSharedLibraries.remove(name);
6821 if (DEBUG_REMOVE && chatty) {
6823 r = new StringBuilder(256);
6834 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
6838 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
6839 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
6840 if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
6847 static final int UPDATE_PERMISSIONS_ALL = 1<<0;
6848 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
6849 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
6851 private void updatePermissionsLPw(String changingPkg,
6852 PackageParser.Package pkgInfo, int flags) {
6853 // Make sure there are no dangling permission trees.
6854 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
6855 while (it.hasNext()) {
6856 final BasePermission bp = it.next();
6857 if (bp.packageSetting == null) {
6858 // We may not yet have parsed the package, so just see if
6859 // we still know about its settings.
6860 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6862 if (bp.packageSetting == null) {
6863 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
6864 + " from package " + bp.sourcePackage);
6866 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6867 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6868 Slog.i(TAG, "Removing old permission tree: " + bp.name
6869 + " from package " + bp.sourcePackage);
6870 flags |= UPDATE_PERMISSIONS_ALL;
6876 // Make sure all dynamic permissions have been assigned to a package,
6877 // and make sure there are no dangling permissions.
6878 it = mSettings.mPermissions.values().iterator();
6879 while (it.hasNext()) {
6880 final BasePermission bp = it.next();
6881 if (bp.type == BasePermission.TYPE_DYNAMIC) {
6882 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
6883 + bp.name + " pkg=" + bp.sourcePackage
6884 + " info=" + bp.pendingInfo);
6885 if (bp.packageSetting == null && bp.pendingInfo != null) {
6886 final BasePermission tree = findPermissionTreeLP(bp.name);
6887 if (tree != null && tree.perm != null) {
6888 bp.packageSetting = tree.packageSetting;
6889 bp.perm = new PackageParser.Permission(tree.perm.owner,
6890 new PermissionInfo(bp.pendingInfo));
6891 bp.perm.info.packageName = tree.perm.info.packageName;
6892 bp.perm.info.name = bp.name;
6897 if (bp.packageSetting == null) {
6898 // We may not yet have parsed the package, so just see if
6899 // we still know about its settings.
6900 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6902 if (bp.packageSetting == null) {
6903 Slog.w(TAG, "Removing dangling permission: " + bp.name
6904 + " from package " + bp.sourcePackage);
6906 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6907 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6908 Slog.i(TAG, "Removing old permission: " + bp.name
6909 + " from package " + bp.sourcePackage);
6910 flags |= UPDATE_PERMISSIONS_ALL;
6916 // Now update the permissions for all packages, in particular
6917 // replace the granted permissions of the system packages.
6918 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
6919 for (PackageParser.Package pkg : mPackages.values()) {
6920 if (pkg != pkgInfo) {
6921 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
6927 if (pkgInfo != null) {
6928 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
6932 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
6933 String packageOfInterest) {
6934 final PackageSetting ps = (PackageSetting) pkg.mExtras;
6938 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
6939 ArraySet<String> origPermissions = gp.grantedPermissions;
6940 boolean changedPermission = false;
6943 ps.permissionsFixed = false;
6945 origPermissions = new ArraySet<String>(gp.grantedPermissions);
6946 gp.grantedPermissions.clear();
6947 gp.gids = mGlobalGids;
6951 if (gp.gids == null) {
6952 gp.gids = mGlobalGids;
6955 final int N = pkg.requestedPermissions.size();
6956 for (int i=0; i<N; i++) {
6957 final String name = pkg.requestedPermissions.get(i);
6958 final boolean required = pkg.requestedPermissionsRequired.get(i);
6959 final BasePermission bp = mSettings.mPermissions.get(name);
6960 if (DEBUG_INSTALL) {
6962 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
6966 if (bp == null || bp.packageSetting == null) {
6967 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
6968 Slog.w(TAG, "Unknown permission " + name
6969 + " in package " + pkg.packageName);
6974 final String perm = bp.name;
6976 boolean allowedSig = false;
6977 if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6978 // Keep track of app op permissions.
6979 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
6981 pkgs = new ArraySet<>();
6982 mAppOpPermissionPackages.put(bp.name, pkgs);
6984 pkgs.add(pkg.packageName);
6986 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
6987 if (level == PermissionInfo.PROTECTION_NORMAL
6988 || level == PermissionInfo.PROTECTION_DANGEROUS) {
6989 // We grant a normal or dangerous permission if any of the following
6991 // 1) The permission is required
6992 // 2) The permission is optional, but was granted in the past
6993 // 3) The permission is optional, but was requested by an
6994 // app in /system (not /data)
6996 // Otherwise, reject the permission.
6997 allowed = (required || origPermissions.contains(perm)
6998 || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
6999 } else if (bp.packageSetting == null) {
7000 // This permission is invalid; skip it.
7002 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
7003 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
7010 if (DEBUG_INSTALL) {
7012 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
7016 if (!isSystemApp(ps) && ps.permissionsFixed) {
7017 // If this is an existing, non-system package, then
7018 // we can't add any new permissions to it.
7019 if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
7020 // Except... if this is a permission that was added
7021 // to the platform (note: need to only do this when
7022 // updating the platform).
7023 allowed = isNewPlatformPermissionForPackage(perm, pkg);
7027 if (!gp.grantedPermissions.contains(perm)) {
7028 changedPermission = true;
7029 gp.grantedPermissions.add(perm);
7030 gp.gids = appendInts(gp.gids, bp.gids);
7031 } else if (!ps.haveGids) {
7032 gp.gids = appendInts(gp.gids, bp.gids);
7035 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7036 Slog.w(TAG, "Not granting permission " + perm
7037 + " to package " + pkg.packageName
7038 + " because it was previously installed without");
7042 if (gp.grantedPermissions.remove(perm)) {
7043 changedPermission = true;
7044 gp.gids = removeInts(gp.gids, bp.gids);
7045 Slog.i(TAG, "Un-granting permission " + perm
7046 + " from package " + pkg.packageName
7047 + " (protectionLevel=" + bp.protectionLevel
7048 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7050 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
7051 // Don't print warning for app op permissions, since it is fine for them
7052 // not to be granted, there is a UI for the user to decide.
7053 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7054 Slog.w(TAG, "Not granting permission " + perm
7055 + " to package " + pkg.packageName
7056 + " (protectionLevel=" + bp.protectionLevel
7057 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7064 if ((changedPermission || replace) && !ps.permissionsFixed &&
7065 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
7066 // This is the first that we have heard about this package, so the
7067 // permissions we have now selected are fixed until explicitly
7069 ps.permissionsFixed = true;
7074 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
7075 boolean allowed = false;
7076 final int NP = PackageParser.NEW_PERMISSIONS.length;
7077 for (int ip=0; ip<NP; ip++) {
7078 final PackageParser.NewPermissionInfo npi
7079 = PackageParser.NEW_PERMISSIONS[ip];
7080 if (npi.name.equals(perm)
7081 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
7083 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
7091 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
7092 BasePermission bp, ArraySet<String> origPermissions) {
7094 allowed = (compareSignatures(
7095 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
7096 == PackageManager.SIGNATURE_MATCH)
7097 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
7098 == PackageManager.SIGNATURE_MATCH);
7099 if (!allowed && (bp.protectionLevel
7100 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
7101 if (isSystemApp(pkg)) {
7102 // For updated system applications, a system permission
7103 // is granted only if it had been defined by the original application.
7104 if (isUpdatedSystemApp(pkg)) {
7105 final PackageSetting sysPs = mSettings
7106 .getDisabledSystemPkgLPr(pkg.packageName);
7107 final GrantedPermissions origGp = sysPs.sharedUser != null
7108 ? sysPs.sharedUser : sysPs;
7110 if (origGp.grantedPermissions.contains(perm)) {
7111 // If the original was granted this permission, we take
7112 // that grant decision as read and propagate it to the
7116 // The system apk may have been updated with an older
7117 // version of the one on the data partition, but which
7118 // granted a new system permission that it didn't have
7119 // before. In this case we do want to allow the app to
7120 // now get the new permission if the ancestral apk is
7121 // privileged to get it.
7122 if (sysPs.pkg != null && sysPs.isPrivileged()) {
7124 j<sysPs.pkg.requestedPermissions.size(); j++) {
7126 sysPs.pkg.requestedPermissions.get(j))) {
7134 allowed = isPrivilegedApp(pkg);
7138 if (!allowed && (bp.protectionLevel
7139 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
7140 // For development permissions, a development permission
7141 // is granted only if it was already granted.
7142 allowed = origPermissions.contains(perm);
7147 final class ActivityIntentResolver
7148 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
7149 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7150 boolean defaultOnly, int userId) {
7151 if (!sUserManager.exists(userId)) return null;
7152 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7153 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7156 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7158 if (!sUserManager.exists(userId)) return null;
7160 return super.queryIntent(intent, resolvedType,
7161 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7164 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7165 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
7166 if (!sUserManager.exists(userId)) return null;
7167 if (packageActivities == null) {
7171 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7172 final int N = packageActivities.size();
7173 ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
7174 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
7176 ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
7177 for (int i = 0; i < N; ++i) {
7178 intentFilters = packageActivities.get(i).intents;
7179 if (intentFilters != null && intentFilters.size() > 0) {
7180 PackageParser.ActivityIntentInfo[] array =
7181 new PackageParser.ActivityIntentInfo[intentFilters.size()];
7182 intentFilters.toArray(array);
7186 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7189 public final void addActivity(PackageParser.Activity a, String type) {
7190 final boolean systemApp = isSystemApp(a.info.applicationInfo);
7191 mActivities.put(a.getComponentName(), a);
7192 if (DEBUG_SHOW_INFO)
7194 TAG, " " + type + " " +
7195 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
7196 if (DEBUG_SHOW_INFO)
7197 Log.v(TAG, " Class=" + a.info.name);
7198 final int NI = a.intents.size();
7199 for (int j=0; j<NI; j++) {
7200 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7201 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
7202 intent.setPriority(0);
7203 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
7204 + a.className + " with priority > 0, forcing to 0");
7206 if (DEBUG_SHOW_INFO) {
7207 Log.v(TAG, " IntentFilter:");
7208 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7210 if (!intent.debugCheck()) {
7211 Log.w(TAG, "==> For Activity " + a.info.name);
7217 public final void removeActivity(PackageParser.Activity a, String type) {
7218 mActivities.remove(a.getComponentName());
7219 if (DEBUG_SHOW_INFO) {
7220 Log.v(TAG, " " + type + " "
7221 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
7222 : a.info.name) + ":");
7223 Log.v(TAG, " Class=" + a.info.name);
7225 final int NI = a.intents.size();
7226 for (int j=0; j<NI; j++) {
7227 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7228 if (DEBUG_SHOW_INFO) {
7229 Log.v(TAG, " IntentFilter:");
7230 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7232 removeFilter(intent);
7237 protected boolean allowFilterResult(
7238 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
7239 ActivityInfo filterAi = filter.activity.info;
7240 for (int i=dest.size()-1; i>=0; i--) {
7241 ActivityInfo destAi = dest.get(i).activityInfo;
7242 if (destAi.name == filterAi.name
7243 && destAi.packageName == filterAi.packageName) {
7251 protected ActivityIntentInfo[] newArray(int size) {
7252 return new ActivityIntentInfo[size];
7256 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
7257 if (!sUserManager.exists(userId)) return true;
7258 PackageParser.Package p = filter.activity.owner;
7260 PackageSetting ps = (PackageSetting)p.mExtras;
7262 // System apps are never considered stopped for purposes of
7263 // filtering, because there may be no way for the user to
7264 // actually re-launch them.
7265 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
7266 && ps.getStopped(userId);
7273 protected boolean isPackageForFilter(String packageName,
7274 PackageParser.ActivityIntentInfo info) {
7275 return packageName.equals(info.activity.owner.packageName);
7279 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
7280 int match, int userId) {
7281 if (!sUserManager.exists(userId)) return null;
7282 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
7285 final PackageParser.Activity activity = info.activity;
7286 if (mSafeMode && (activity.info.applicationInfo.flags
7287 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7290 PackageSetting ps = (PackageSetting) activity.owner.mExtras;
7294 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
7295 ps.readUserState(userId), userId);
7299 final ResolveInfo res = new ResolveInfo();
7300 res.activityInfo = ai;
7301 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7304 res.priority = info.getPriority();
7305 res.preferredOrder = activity.owner.mPreferredOrder;
7306 //System.out.println("Result: " + res.activityInfo.className +
7307 // " = " + res.priority);
7309 res.isDefault = info.hasDefault;
7310 res.labelRes = info.labelRes;
7311 res.nonLocalizedLabel = info.nonLocalizedLabel;
7312 if (userNeedsBadging(userId)) {
7313 res.noResourceId = true;
7315 res.icon = info.icon;
7317 res.system = isSystemApp(res.activityInfo.applicationInfo);
7322 protected void sortResults(List<ResolveInfo> results) {
7323 Collections.sort(results, mResolvePrioritySorter);
7327 protected void dumpFilter(PrintWriter out, String prefix,
7328 PackageParser.ActivityIntentInfo filter) {
7329 out.print(prefix); out.print(
7330 Integer.toHexString(System.identityHashCode(filter.activity)));
7332 filter.activity.printComponentShortName(out);
7333 out.print(" filter ");
7334 out.println(Integer.toHexString(System.identityHashCode(filter)));
7337 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7338 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7339 // final List<ResolveInfo> retList = Lists.newArrayList();
7340 // while (i.hasNext()) {
7341 // final ResolveInfo resolveInfo = i.next();
7342 // if (isEnabledLP(resolveInfo.activityInfo)) {
7343 // retList.add(resolveInfo);
7349 // Keys are String (activity class name), values are Activity.
7350 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
7351 = new ArrayMap<ComponentName, PackageParser.Activity>();
7355 private final class ServiceIntentResolver
7356 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
7357 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7358 boolean defaultOnly, int userId) {
7359 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7360 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7363 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7365 if (!sUserManager.exists(userId)) return null;
7367 return super.queryIntent(intent, resolvedType,
7368 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7371 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7372 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
7373 if (!sUserManager.exists(userId)) return null;
7374 if (packageServices == null) {
7378 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7379 final int N = packageServices.size();
7380 ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
7381 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
7383 ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
7384 for (int i = 0; i < N; ++i) {
7385 intentFilters = packageServices.get(i).intents;
7386 if (intentFilters != null && intentFilters.size() > 0) {
7387 PackageParser.ServiceIntentInfo[] array =
7388 new PackageParser.ServiceIntentInfo[intentFilters.size()];
7389 intentFilters.toArray(array);
7393 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7396 public final void addService(PackageParser.Service s) {
7397 mServices.put(s.getComponentName(), s);
7398 if (DEBUG_SHOW_INFO) {
7400 + (s.info.nonLocalizedLabel != null
7401 ? s.info.nonLocalizedLabel : s.info.name) + ":");
7402 Log.v(TAG, " Class=" + s.info.name);
7404 final int NI = s.intents.size();
7406 for (j=0; j<NI; j++) {
7407 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7408 if (DEBUG_SHOW_INFO) {
7409 Log.v(TAG, " IntentFilter:");
7410 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7412 if (!intent.debugCheck()) {
7413 Log.w(TAG, "==> For Service " + s.info.name);
7419 public final void removeService(PackageParser.Service s) {
7420 mServices.remove(s.getComponentName());
7421 if (DEBUG_SHOW_INFO) {
7422 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
7423 ? s.info.nonLocalizedLabel : s.info.name) + ":");
7424 Log.v(TAG, " Class=" + s.info.name);
7426 final int NI = s.intents.size();
7428 for (j=0; j<NI; j++) {
7429 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7430 if (DEBUG_SHOW_INFO) {
7431 Log.v(TAG, " IntentFilter:");
7432 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7434 removeFilter(intent);
7439 protected boolean allowFilterResult(
7440 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
7441 ServiceInfo filterSi = filter.service.info;
7442 for (int i=dest.size()-1; i>=0; i--) {
7443 ServiceInfo destAi = dest.get(i).serviceInfo;
7444 if (destAi.name == filterSi.name
7445 && destAi.packageName == filterSi.packageName) {
7453 protected PackageParser.ServiceIntentInfo[] newArray(int size) {
7454 return new PackageParser.ServiceIntentInfo[size];
7458 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
7459 if (!sUserManager.exists(userId)) return true;
7460 PackageParser.Package p = filter.service.owner;
7462 PackageSetting ps = (PackageSetting)p.mExtras;
7464 // System apps are never considered stopped for purposes of
7465 // filtering, because there may be no way for the user to
7466 // actually re-launch them.
7467 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7468 && ps.getStopped(userId);
7475 protected boolean isPackageForFilter(String packageName,
7476 PackageParser.ServiceIntentInfo info) {
7477 return packageName.equals(info.service.owner.packageName);
7481 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
7482 int match, int userId) {
7483 if (!sUserManager.exists(userId)) return null;
7484 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
7485 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
7488 final PackageParser.Service service = info.service;
7489 if (mSafeMode && (service.info.applicationInfo.flags
7490 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7493 PackageSetting ps = (PackageSetting) service.owner.mExtras;
7497 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
7498 ps.readUserState(userId), userId);
7502 final ResolveInfo res = new ResolveInfo();
7503 res.serviceInfo = si;
7504 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7505 res.filter = filter;
7507 res.priority = info.getPriority();
7508 res.preferredOrder = service.owner.mPreferredOrder;
7509 //System.out.println("Result: " + res.activityInfo.className +
7510 // " = " + res.priority);
7512 res.isDefault = info.hasDefault;
7513 res.labelRes = info.labelRes;
7514 res.nonLocalizedLabel = info.nonLocalizedLabel;
7515 res.icon = info.icon;
7516 res.system = isSystemApp(res.serviceInfo.applicationInfo);
7521 protected void sortResults(List<ResolveInfo> results) {
7522 Collections.sort(results, mResolvePrioritySorter);
7526 protected void dumpFilter(PrintWriter out, String prefix,
7527 PackageParser.ServiceIntentInfo filter) {
7528 out.print(prefix); out.print(
7529 Integer.toHexString(System.identityHashCode(filter.service)));
7531 filter.service.printComponentShortName(out);
7532 out.print(" filter ");
7533 out.println(Integer.toHexString(System.identityHashCode(filter)));
7536 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7537 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7538 // final List<ResolveInfo> retList = Lists.newArrayList();
7539 // while (i.hasNext()) {
7540 // final ResolveInfo resolveInfo = (ResolveInfo) i;
7541 // if (isEnabledLP(resolveInfo.serviceInfo)) {
7542 // retList.add(resolveInfo);
7548 // Keys are String (activity class name), values are Activity.
7549 private final ArrayMap<ComponentName, PackageParser.Service> mServices
7550 = new ArrayMap<ComponentName, PackageParser.Service>();
7554 private final class ProviderIntentResolver
7555 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
7556 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7557 boolean defaultOnly, int userId) {
7558 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7559 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7562 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7564 if (!sUserManager.exists(userId))
7567 return super.queryIntent(intent, resolvedType,
7568 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7571 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7572 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
7573 if (!sUserManager.exists(userId))
7575 if (packageProviders == null) {
7579 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
7580 final int N = packageProviders.size();
7581 ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
7582 new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
7584 ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
7585 for (int i = 0; i < N; ++i) {
7586 intentFilters = packageProviders.get(i).intents;
7587 if (intentFilters != null && intentFilters.size() > 0) {
7588 PackageParser.ProviderIntentInfo[] array =
7589 new PackageParser.ProviderIntentInfo[intentFilters.size()];
7590 intentFilters.toArray(array);
7594 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7597 public final void addProvider(PackageParser.Provider p) {
7598 if (mProviders.containsKey(p.getComponentName())) {
7599 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
7603 mProviders.put(p.getComponentName(), p);
7604 if (DEBUG_SHOW_INFO) {
7606 + (p.info.nonLocalizedLabel != null
7607 ? p.info.nonLocalizedLabel : p.info.name) + ":");
7608 Log.v(TAG, " Class=" + p.info.name);
7610 final int NI = p.intents.size();
7612 for (j = 0; j < NI; j++) {
7613 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7614 if (DEBUG_SHOW_INFO) {
7615 Log.v(TAG, " IntentFilter:");
7616 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7618 if (!intent.debugCheck()) {
7619 Log.w(TAG, "==> For Provider " + p.info.name);
7625 public final void removeProvider(PackageParser.Provider p) {
7626 mProviders.remove(p.getComponentName());
7627 if (DEBUG_SHOW_INFO) {
7628 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
7629 ? p.info.nonLocalizedLabel : p.info.name) + ":");
7630 Log.v(TAG, " Class=" + p.info.name);
7632 final int NI = p.intents.size();
7634 for (j = 0; j < NI; j++) {
7635 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7636 if (DEBUG_SHOW_INFO) {
7637 Log.v(TAG, " IntentFilter:");
7638 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
7640 removeFilter(intent);
7645 protected boolean allowFilterResult(
7646 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
7647 ProviderInfo filterPi = filter.provider.info;
7648 for (int i = dest.size() - 1; i >= 0; i--) {
7649 ProviderInfo destPi = dest.get(i).providerInfo;
7650 if (destPi.name == filterPi.name
7651 && destPi.packageName == filterPi.packageName) {
7659 protected PackageParser.ProviderIntentInfo[] newArray(int size) {
7660 return new PackageParser.ProviderIntentInfo[size];
7664 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
7665 if (!sUserManager.exists(userId))
7667 PackageParser.Package p = filter.provider.owner;
7669 PackageSetting ps = (PackageSetting) p.mExtras;
7671 // System apps are never considered stopped for purposes of
7672 // filtering, because there may be no way for the user to
7673 // actually re-launch them.
7674 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7675 && ps.getStopped(userId);
7682 protected boolean isPackageForFilter(String packageName,
7683 PackageParser.ProviderIntentInfo info) {
7684 return packageName.equals(info.provider.owner.packageName);
7688 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
7689 int match, int userId) {
7690 if (!sUserManager.exists(userId))
7692 final PackageParser.ProviderIntentInfo info = filter;
7693 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
7696 final PackageParser.Provider provider = info.provider;
7697 if (mSafeMode && (provider.info.applicationInfo.flags
7698 & ApplicationInfo.FLAG_SYSTEM) == 0) {
7701 PackageSetting ps = (PackageSetting) provider.owner.mExtras;
7705 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
7706 ps.readUserState(userId), userId);
7710 final ResolveInfo res = new ResolveInfo();
7711 res.providerInfo = pi;
7712 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
7713 res.filter = filter;
7715 res.priority = info.getPriority();
7716 res.preferredOrder = provider.owner.mPreferredOrder;
7718 res.isDefault = info.hasDefault;
7719 res.labelRes = info.labelRes;
7720 res.nonLocalizedLabel = info.nonLocalizedLabel;
7721 res.icon = info.icon;
7722 res.system = isSystemApp(res.providerInfo.applicationInfo);
7727 protected void sortResults(List<ResolveInfo> results) {
7728 Collections.sort(results, mResolvePrioritySorter);
7732 protected void dumpFilter(PrintWriter out, String prefix,
7733 PackageParser.ProviderIntentInfo filter) {
7736 Integer.toHexString(System.identityHashCode(filter.provider)));
7738 filter.provider.printComponentShortName(out);
7739 out.print(" filter ");
7740 out.println(Integer.toHexString(System.identityHashCode(filter)));
7743 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
7744 = new ArrayMap<ComponentName, PackageParser.Provider>();
7748 private static final Comparator<ResolveInfo> mResolvePrioritySorter =
7749 new Comparator<ResolveInfo>() {
7750 public int compare(ResolveInfo r1, ResolveInfo r2) {
7751 int v1 = r1.priority;
7752 int v2 = r2.priority;
7753 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
7755 return (v1 > v2) ? -1 : 1;
7757 v1 = r1.preferredOrder;
7758 v2 = r2.preferredOrder;
7760 return (v1 > v2) ? -1 : 1;
7762 if (r1.isDefault != r2.isDefault) {
7763 return r1.isDefault ? -1 : 1;
7767 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
7769 return (v1 > v2) ? -1 : 1;
7771 if (r1.system != r2.system) {
7772 return r1.system ? -1 : 1;
7778 private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
7779 new Comparator<ProviderInfo>() {
7780 public int compare(ProviderInfo p1, ProviderInfo p2) {
7781 final int v1 = p1.initOrder;
7782 final int v2 = p2.initOrder;
7783 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
7787 static final void sendPackageBroadcast(String action, String pkg,
7788 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
7790 IActivityManager am = ActivityManagerNative.getDefault();
7793 if (userIds == null) {
7794 userIds = am.getRunningUserIds();
7796 for (int id : userIds) {
7797 final Intent intent = new Intent(action,
7798 pkg != null ? Uri.fromParts("package", pkg, null) : null);
7799 if (extras != null) {
7800 intent.putExtras(extras);
7802 if (targetPkg != null) {
7803 intent.setPackage(targetPkg);
7805 // Modify the UID when posting to other users
7806 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
7807 if (uid > 0 && UserHandle.getUserId(uid) != id) {
7808 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
7809 intent.putExtra(Intent.EXTRA_UID, uid);
7811 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
7812 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
7813 if (DEBUG_BROADCASTS) {
7814 RuntimeException here = new RuntimeException("here");
7815 here.fillInStackTrace();
7816 Slog.d(TAG, "Sending to user " + id + ": "
7817 + intent.toShortString(false, true, false, false)
7818 + " " + intent.getExtras(), here);
7820 am.broadcastIntent(null, intent, null, finishedReceiver,
7821 0, null, null, null, android.app.AppOpsManager.OP_NONE,
7822 finishedReceiver != null, false, id);
7824 } catch (RemoteException ex) {
7830 * Check if the external storage media is available. This is true if there
7831 * is a mounted external storage medium or if the external storage is
7834 private boolean isExternalMediaAvailable() {
7835 return mMediaMounted || Environment.isExternalStorageEmulated();
7839 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
7841 synchronized (mPackages) {
7842 if (!isExternalMediaAvailable()) {
7843 // If the external storage is no longer mounted at this point,
7844 // the caller may not have been able to delete all of this
7845 // packages files and can not delete any more. Bail.
7848 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
7849 if (lastPackage != null) {
7850 pkgs.remove(lastPackage);
7852 if (pkgs.size() > 0) {
7859 void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
7860 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
7861 userId, andCode ? 1 : 0, packageName);
7865 if (mPostSystemReadyMessages == null) {
7866 mPostSystemReadyMessages = new ArrayList<>();
7868 mPostSystemReadyMessages.add(msg);
7872 void startCleaningPackages() {
7874 synchronized (mPackages) {
7875 if (!isExternalMediaAvailable()) {
7878 if (mSettings.mPackagesToBeCleaned.isEmpty()) {
7882 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
7883 intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
7884 IActivityManager am = ActivityManagerNative.getDefault();
7887 am.startService(null, intent, null, UserHandle.USER_OWNER);
7888 } catch (RemoteException e) {
7894 public void installPackage(String originPath, IPackageInstallObserver2 observer,
7895 int installFlags, String installerPackageName, VerificationParams verificationParams,
7896 String packageAbiOverride) {
7897 installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
7898 packageAbiOverride, UserHandle.getCallingUserId());
7902 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
7903 int installFlags, String installerPackageName, VerificationParams verificationParams,
7904 String packageAbiOverride, int userId) {
7905 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
7907 final int callingUid = Binder.getCallingUid();
7908 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
7910 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
7912 if (observer != null) {
7913 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
7915 } catch (RemoteException re) {
7920 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
7921 installFlags |= PackageManager.INSTALL_FROM_ADB;
7924 // Caller holds INSTALL_PACKAGES permission, so we're less strict
7925 // about installerPackageName.
7927 installFlags &= ~PackageManager.INSTALL_FROM_ADB;
7928 installFlags &= ~PackageManager.INSTALL_ALL_USERS;
7932 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
7933 user = UserHandle.ALL;
7935 user = new UserHandle(userId);
7938 verificationParams.setInstallerUid(callingUid);
7940 final File originFile = new File(originPath);
7941 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
7943 final Message msg = mHandler.obtainMessage(INIT_COPY);
7944 msg.obj = new InstallParams(origin, observer, installFlags,
7945 installerPackageName, verificationParams, user, packageAbiOverride);
7946 mHandler.sendMessage(msg);
7949 void installStage(String packageName, File stagedDir, String stagedCid,
7950 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
7951 String installerPackageName, int installerUid, UserHandle user) {
7952 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
7953 params.referrerUri, installerUid, null);
7955 final OriginInfo origin;
7956 if (stagedDir != null) {
7957 origin = OriginInfo.fromStagedFile(stagedDir);
7959 origin = OriginInfo.fromStagedContainer(stagedCid);
7962 final Message msg = mHandler.obtainMessage(INIT_COPY);
7963 msg.obj = new InstallParams(origin, observer, params.installFlags,
7964 installerPackageName, verifParams, user, params.abiOverride);
7965 mHandler.sendMessage(msg);
7968 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
7969 Bundle extras = new Bundle(1);
7970 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
7972 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
7973 packageName, extras, null, null, new int[] {userId});
7975 IActivityManager am = ActivityManagerNative.getDefault();
7976 final boolean isSystem =
7977 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
7978 if (isSystem && am.isUserRunning(userId, false)) {
7979 // The just-installed/enabled app is bundled on the system, so presumed
7980 // to be able to run automatically without needing an explicit launch.
7981 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
7982 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
7983 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
7984 .setPackage(packageName);
7985 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
7986 android.app.AppOpsManager.OP_NONE, false, false, userId);
7988 } catch (RemoteException e) {
7990 Slog.w(TAG, "Unable to bootstrap installed package", e);
7995 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
7997 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
7998 PackageSetting pkgSetting;
7999 final int uid = Binder.getCallingUid();
8000 enforceCrossUserPermission(uid, userId, true, true,
8001 "setApplicationHiddenSetting for user " + userId);
8003 if (hidden && isPackageDeviceAdmin(packageName, userId)) {
8004 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
8008 long callingId = Binder.clearCallingIdentity();
8010 boolean sendAdded = false;
8011 boolean sendRemoved = false;
8013 synchronized (mPackages) {
8014 pkgSetting = mSettings.mPackages.get(packageName);
8015 if (pkgSetting == null) {
8018 if (pkgSetting.getHidden(userId) != hidden) {
8019 pkgSetting.setHidden(hidden, userId);
8020 mSettings.writePackageRestrictionsLPr(userId);
8029 sendPackageAddedForUser(packageName, pkgSetting, userId);
8033 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
8035 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
8038 Binder.restoreCallingIdentity(callingId);
8043 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
8045 final PackageRemovedInfo info = new PackageRemovedInfo();
8046 info.removedPackage = packageName;
8047 info.removedUsers = new int[] {userId};
8048 info.uid = UserHandle.getUid(userId, pkgSetting.appId);
8049 info.sendBroadcast(false, false, false);
8053 * Returns true if application is not found or there was an error. Otherwise it returns
8054 * the hidden state of the package for the given user.
8057 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
8058 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8059 enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
8060 false, "getApplicationHidden for user " + userId);
8061 PackageSetting pkgSetting;
8062 long callingId = Binder.clearCallingIdentity();
8065 synchronized (mPackages) {
8066 pkgSetting = mSettings.mPackages.get(packageName);
8067 if (pkgSetting == null) {
8070 return pkgSetting.getHidden(userId);
8073 Binder.restoreCallingIdentity(callingId);
8081 public int installExistingPackageAsUser(String packageName, int userId) {
8082 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
8084 PackageSetting pkgSetting;
8085 final int uid = Binder.getCallingUid();
8086 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
8088 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8089 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
8092 long callingId = Binder.clearCallingIdentity();
8094 boolean sendAdded = false;
8095 Bundle extras = new Bundle(1);
8098 synchronized (mPackages) {
8099 pkgSetting = mSettings.mPackages.get(packageName);
8100 if (pkgSetting == null) {
8101 return PackageManager.INSTALL_FAILED_INVALID_URI;
8103 if (!pkgSetting.getInstalled(userId)) {
8104 pkgSetting.setInstalled(true, userId);
8105 pkgSetting.setHidden(false, userId);
8106 mSettings.writePackageRestrictionsLPr(userId);
8112 sendPackageAddedForUser(packageName, pkgSetting, userId);
8115 Binder.restoreCallingIdentity(callingId);
8118 return PackageManager.INSTALL_SUCCEEDED;
8121 boolean isUserRestricted(int userId, String restrictionKey) {
8122 Bundle restrictions = sUserManager.getUserRestrictions(userId);
8123 if (restrictions.getBoolean(restrictionKey, false)) {
8124 Log.w(TAG, "User is restricted: " + restrictionKey);
8131 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
8132 mContext.enforceCallingOrSelfPermission(
8133 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8134 "Only package verification agents can verify applications");
8136 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8137 final PackageVerificationResponse response = new PackageVerificationResponse(
8138 verificationCode, Binder.getCallingUid());
8141 mHandler.sendMessage(msg);
8145 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
8146 long millisecondsToDelay) {
8147 mContext.enforceCallingOrSelfPermission(
8148 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8149 "Only package verification agents can extend verification timeouts");
8151 final PackageVerificationState state = mPendingVerification.get(id);
8152 final PackageVerificationResponse response = new PackageVerificationResponse(
8153 verificationCodeAtTimeout, Binder.getCallingUid());
8155 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
8156 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
8158 if (millisecondsToDelay < 0) {
8159 millisecondsToDelay = 0;
8161 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
8162 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
8163 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
8166 if ((state != null) && !state.timeoutExtended()) {
8167 state.extendTimeout();
8169 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8172 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
8176 private void broadcastPackageVerified(int verificationId, Uri packageUri,
8177 int verificationCode, UserHandle user) {
8178 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
8179 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
8180 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8181 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8182 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
8184 mContext.sendBroadcastAsUser(intent, user,
8185 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
8188 private ComponentName matchComponentForVerifier(String packageName,
8189 List<ResolveInfo> receivers) {
8190 ActivityInfo targetReceiver = null;
8192 final int NR = receivers.size();
8193 for (int i = 0; i < NR; i++) {
8194 final ResolveInfo info = receivers.get(i);
8195 if (info.activityInfo == null) {
8199 if (packageName.equals(info.activityInfo.packageName)) {
8200 targetReceiver = info.activityInfo;
8205 if (targetReceiver == null) {
8209 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
8212 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
8213 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
8214 if (pkgInfo.verifiers.length == 0) {
8218 final int N = pkgInfo.verifiers.length;
8219 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
8220 for (int i = 0; i < N; i++) {
8221 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
8223 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
8229 final int verifierUid = getUidForVerifier(verifierInfo);
8230 if (verifierUid == -1) {
8235 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
8236 + " with the correct signature");
8238 sufficientVerifiers.add(comp);
8239 verificationState.addSufficientVerifier(verifierUid);
8242 return sufficientVerifiers;
8245 private int getUidForVerifier(VerifierInfo verifierInfo) {
8246 synchronized (mPackages) {
8247 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
8250 } else if (pkg.mSignatures.length != 1) {
8251 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8252 + " has more than one signature; ignoring");
8257 * If the public key of the package's signature does not match
8258 * our expected public key, then this is a different package and
8262 final byte[] expectedPublicKey;
8264 final Signature verifierSig = pkg.mSignatures[0];
8265 final PublicKey publicKey = verifierSig.getPublicKey();
8266 expectedPublicKey = publicKey.getEncoded();
8267 } catch (CertificateException e) {
8271 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
8273 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
8274 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8275 + " does not have the expected public key; ignoring");
8279 return pkg.applicationInfo.uid;
8284 public void finishPackageInstall(int token) {
8285 enforceSystemOrRoot("Only the system is allowed to finish installs");
8287 if (DEBUG_INSTALL) {
8288 Slog.v(TAG, "BM finishing package install for " + token);
8291 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8292 mHandler.sendMessage(msg);
8296 * Get the verification agent timeout.
8298 * @return verification timeout in milliseconds
8300 private long getVerificationTimeout() {
8301 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8302 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
8303 DEFAULT_VERIFICATION_TIMEOUT);
8307 * Get the default verification agent response code.
8309 * @return default verification response code
8311 private int getDefaultVerificationResponse() {
8312 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8313 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
8314 DEFAULT_VERIFICATION_RESPONSE);
8318 * Check whether or not package verification has been enabled.
8320 * @return true if verification should be performed
8322 private boolean isVerificationEnabled(int userId, int installFlags) {
8323 if (!DEFAULT_VERIFY_ENABLE) {
8327 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
8329 // Check if installing from ADB
8330 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
8331 // Do not run verification in a test harness environment
8332 if (ActivityManager.isRunningInTestHarness()) {
8335 if (ensureVerifyAppsEnabled) {
8338 // Check if the developer does not want package verification for ADB installs
8339 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8340 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
8345 if (ensureVerifyAppsEnabled) {
8349 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8350 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
8354 * Get the "allow unknown sources" setting.
8356 * @return the current "allow unknown sources" setting
8358 private int getUnknownSourcesSettings() {
8359 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8360 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
8365 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
8366 final int uid = Binder.getCallingUid();
8368 synchronized (mPackages) {
8369 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
8370 if (targetPackageSetting == null) {
8371 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
8374 PackageSetting installerPackageSetting;
8375 if (installerPackageName != null) {
8376 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
8377 if (installerPackageSetting == null) {
8378 throw new IllegalArgumentException("Unknown installer package: "
8379 + installerPackageName);
8382 installerPackageSetting = null;
8385 Signature[] callerSignature;
8386 Object obj = mSettings.getUserIdLPr(uid);
8388 if (obj instanceof SharedUserSetting) {
8389 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
8390 } else if (obj instanceof PackageSetting) {
8391 callerSignature = ((PackageSetting)obj).signatures.mSignatures;
8393 throw new SecurityException("Bad object " + obj + " for uid " + uid);
8396 throw new SecurityException("Unknown calling uid " + uid);
8399 // Verify: can't set installerPackageName to a package that is
8400 // not signed with the same cert as the caller.
8401 if (installerPackageSetting != null) {
8402 if (compareSignatures(callerSignature,
8403 installerPackageSetting.signatures.mSignatures)
8404 != PackageManager.SIGNATURE_MATCH) {
8405 throw new SecurityException(
8406 "Caller does not have same cert as new installer package "
8407 + installerPackageName);
8411 // Verify: if target already has an installer package, it must
8412 // be signed with the same cert as the caller.
8413 if (targetPackageSetting.installerPackageName != null) {
8414 PackageSetting setting = mSettings.mPackages.get(
8415 targetPackageSetting.installerPackageName);
8416 // If the currently set package isn't valid, then it's always
8417 // okay to change it.
8418 if (setting != null) {
8419 if (compareSignatures(callerSignature,
8420 setting.signatures.mSignatures)
8421 != PackageManager.SIGNATURE_MATCH) {
8422 throw new SecurityException(
8423 "Caller does not have same cert as old installer package "
8424 + targetPackageSetting.installerPackageName);
8430 targetPackageSetting.installerPackageName = installerPackageName;
8431 scheduleWriteSettingsLocked();
8435 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
8436 // Queue up an async operation since the package installation may take a little while.
8437 mHandler.post(new Runnable() {
8439 mHandler.removeCallbacks(this);
8440 // Result object to be returned
8441 PackageInstalledInfo res = new PackageInstalledInfo();
8442 res.returnCode = currentStatus;
8445 res.removedInfo = new PackageRemovedInfo();
8446 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
8447 args.doPreInstall(res.returnCode);
8448 synchronized (mInstallLock) {
8449 installPackageLI(args, res);
8451 args.doPostInstall(res.returnCode, res.uid);
8454 // A restore should be performed at this point if (a) the install
8455 // succeeded, (b) the operation is not an update, and (c) the new
8456 // package has not opted out of backup participation.
8457 final boolean update = res.removedInfo.removedPackage != null;
8458 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
8459 boolean doRestore = !update
8460 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
8462 // Set up the post-install work request bookkeeping. This will be used
8463 // and cleaned up by the post-install event handling regardless of whether
8464 // there's a restore pass performed. Token values are >= 1.
8466 if (mNextInstallToken < 0) mNextInstallToken = 1;
8467 token = mNextInstallToken++;
8469 PostInstallData data = new PostInstallData(args, res);
8470 mRunningInstalls.put(token, data);
8471 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
8473 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
8474 // Pass responsibility to the Backup Manager. It will perform a
8475 // restore if appropriate, then pass responsibility back to the
8476 // Package Manager to run the post-install observer callbacks
8478 IBackupManager bm = IBackupManager.Stub.asInterface(
8479 ServiceManager.getService(Context.BACKUP_SERVICE));
8481 if (DEBUG_INSTALL) Log.v(TAG, "token " + token
8482 + " to BM for possible restore");
8484 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
8485 } catch (RemoteException e) {
8486 // can't happen; the backup manager is local
8487 } catch (Exception e) {
8488 Slog.e(TAG, "Exception trying to enqueue restore", e);
8492 Slog.e(TAG, "Backup Manager not found!");
8498 // No restore possible, or the Backup Manager was mysteriously not
8499 // available -- just fire the post-install work request directly.
8500 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
8501 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8502 mHandler.sendMessage(msg);
8508 private abstract class HandlerParams {
8509 private static final int MAX_RETRIES = 4;
8512 * Number of times startCopy() has been attempted and had a non-fatal
8515 private int mRetries = 0;
8517 /** User handle for the user requesting the information or installation. */
8518 private final UserHandle mUser;
8520 HandlerParams(UserHandle user) {
8524 UserHandle getUser() {
8528 final boolean startCopy() {
8531 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
8533 if (++mRetries > MAX_RETRIES) {
8534 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
8535 mHandler.sendEmptyMessage(MCS_GIVE_UP);
8536 handleServiceError();
8542 } catch (RemoteException e) {
8543 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
8544 mHandler.sendEmptyMessage(MCS_RECONNECT);
8551 final void serviceError() {
8552 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
8553 handleServiceError();
8557 abstract void handleStartCopy() throws RemoteException;
8558 abstract void handleServiceError();
8559 abstract void handleReturnCode();
8562 class MeasureParams extends HandlerParams {
8563 private final PackageStats mStats;
8564 private boolean mSuccess;
8566 private final IPackageStatsObserver mObserver;
8568 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
8569 super(new UserHandle(stats.userHandle));
8570 mObserver = observer;
8575 public String toString() {
8576 return "MeasureParams{"
8577 + Integer.toHexString(System.identityHashCode(this))
8578 + " " + mStats.packageName + "}";
8582 void handleStartCopy() throws RemoteException {
8583 synchronized (mInstallLock) {
8584 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
8588 final boolean mounted;
8589 if (Environment.isExternalStorageEmulated()) {
8592 final String status = Environment.getExternalStorageState();
8593 mounted = (Environment.MEDIA_MOUNTED.equals(status)
8594 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
8598 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
8600 mStats.externalCacheSize = calculateDirectorySize(mContainerService,
8601 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
8603 mStats.externalDataSize = calculateDirectorySize(mContainerService,
8604 userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
8606 // Always subtract cache size, since it's a subdirectory
8607 mStats.externalDataSize -= mStats.externalCacheSize;
8609 mStats.externalMediaSize = calculateDirectorySize(mContainerService,
8610 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
8612 mStats.externalObbSize = calculateDirectorySize(mContainerService,
8613 userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
8619 void handleReturnCode() {
8620 if (mObserver != null) {
8622 mObserver.onGetStatsCompleted(mStats, mSuccess);
8623 } catch (RemoteException e) {
8624 Slog.i(TAG, "Observer no longer exists.");
8630 void handleServiceError() {
8631 Slog.e(TAG, "Could not measure application " + mStats.packageName
8632 + " external storage");
8636 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
8637 throws RemoteException {
8639 for (File path : paths) {
8640 result += mcs.calculateDirectorySize(path.getAbsolutePath());
8645 private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
8646 for (File path : paths) {
8648 mcs.clearDirectory(path.getAbsolutePath());
8649 } catch (RemoteException e) {
8654 static class OriginInfo {
8656 * Location where install is coming from, before it has been
8657 * copied/renamed into place. This could be a single monolithic APK
8658 * file, or a cluster directory. This location may be untrusted.
8664 * Flag indicating that {@link #file} or {@link #cid} has already been
8665 * staged, meaning downstream users don't need to defensively copy the
8668 final boolean staged;
8671 * Flag indicating that {@link #file} or {@link #cid} is an already
8672 * installed app that is being moved.
8674 final boolean existing;
8676 final String resolvedPath;
8677 final File resolvedFile;
8679 static OriginInfo fromNothing() {
8680 return new OriginInfo(null, null, false, false);
8683 static OriginInfo fromUntrustedFile(File file) {
8684 return new OriginInfo(file, null, false, false);
8687 static OriginInfo fromExistingFile(File file) {
8688 return new OriginInfo(file, null, false, true);
8691 static OriginInfo fromStagedFile(File file) {
8692 return new OriginInfo(file, null, true, false);
8695 static OriginInfo fromStagedContainer(String cid) {
8696 return new OriginInfo(null, cid, true, false);
8699 private OriginInfo(File file, String cid, boolean staged, boolean existing) {
8702 this.staged = staged;
8703 this.existing = existing;
8706 resolvedPath = PackageHelper.getSdDir(cid);
8707 resolvedFile = new File(resolvedPath);
8708 } else if (file != null) {
8709 resolvedPath = file.getAbsolutePath();
8710 resolvedFile = file;
8712 resolvedPath = null;
8713 resolvedFile = null;
8718 class InstallParams extends HandlerParams {
8719 final OriginInfo origin;
8720 final IPackageInstallObserver2 observer;
8722 final String installerPackageName;
8723 final VerificationParams verificationParams;
8724 private InstallArgs mArgs;
8726 final String packageAbiOverride;
8728 InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
8729 String installerPackageName, VerificationParams verificationParams, UserHandle user,
8730 String packageAbiOverride) {
8732 this.origin = origin;
8733 this.observer = observer;
8734 this.installFlags = installFlags;
8735 this.installerPackageName = installerPackageName;
8736 this.verificationParams = verificationParams;
8737 this.packageAbiOverride = packageAbiOverride;
8741 public String toString() {
8742 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
8743 + " file=" + origin.file + " cid=" + origin.cid + "}";
8746 public ManifestDigest getManifestDigest() {
8747 if (verificationParams == null) {
8750 return verificationParams.getManifestDigest();
8753 private int installLocationPolicy(PackageInfoLite pkgLite) {
8754 String packageName = pkgLite.packageName;
8755 int installLocation = pkgLite.installLocation;
8756 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8758 synchronized (mPackages) {
8759 PackageParser.Package pkg = mPackages.get(packageName);
8761 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
8762 // Check for downgrading.
8763 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
8764 if (pkgLite.versionCode < pkg.mVersionCode) {
8765 Slog.w(TAG, "Can't install update of " + packageName
8766 + " update version " + pkgLite.versionCode
8767 + " is older than installed version "
8768 + pkg.mVersionCode);
8769 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
8772 // Check for updated system application.
8773 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8775 Slog.w(TAG, "Cannot install update to system app on sdcard");
8776 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
8778 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8781 // Install flag overrides everything.
8782 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8784 // If current upgrade specifies particular preference
8785 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
8786 // Application explicitly specified internal.
8787 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8788 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
8789 // App explictly prefers external. Let policy decide
8791 // Prefer previous location
8792 if (isExternal(pkg)) {
8793 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8795 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8799 // Invalid install. Return error code
8800 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
8804 // All the special cases have been taken care of.
8805 // Return result based on recommended install location.
8807 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8809 return pkgLite.recommendedInstallLocation;
8813 * Invoke remote method to get package information and install
8814 * location values. Override install location based on default
8815 * policy if needed and then create install arguments based
8816 * on the install location.
8818 public void handleStartCopy() throws RemoteException {
8819 int ret = PackageManager.INSTALL_SUCCEEDED;
8821 // If we're already staged, we've firmly committed to an install location
8822 if (origin.staged) {
8823 if (origin.file != null) {
8824 installFlags |= PackageManager.INSTALL_INTERNAL;
8825 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8826 } else if (origin.cid != null) {
8827 installFlags |= PackageManager.INSTALL_EXTERNAL;
8828 installFlags &= ~PackageManager.INSTALL_INTERNAL;
8830 throw new IllegalStateException("Invalid stage location");
8834 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8835 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
8837 PackageInfoLite pkgLite = null;
8839 if (onInt && onSd) {
8840 // Check if both bits are set.
8841 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
8842 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8844 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
8845 packageAbiOverride);
8848 * If we have too little free space, try to free cache
8851 if (!origin.staged && pkgLite.recommendedInstallLocation
8852 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8853 // TODO: focus freeing disk space on the target device
8854 final StorageManager storage = StorageManager.from(mContext);
8855 final long lowThreshold = storage.getStorageLowBytes(
8856 Environment.getDataDirectory());
8858 final long sizeBytes = mContainerService.calculateInstalledSize(
8859 origin.resolvedPath, isForwardLocked(), packageAbiOverride);
8861 if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
8862 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
8863 installFlags, packageAbiOverride);
8867 * The cache free must have deleted the file we
8868 * downloaded to install.
8870 * TODO: fix the "freeCache" call to not delete
8871 * the file we care about.
8873 if (pkgLite.recommendedInstallLocation
8874 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8875 pkgLite.recommendedInstallLocation
8876 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
8881 if (ret == PackageManager.INSTALL_SUCCEEDED) {
8882 int loc = pkgLite.recommendedInstallLocation;
8883 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
8884 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8885 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
8886 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8887 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8888 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8889 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
8890 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
8891 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8892 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
8893 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
8894 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
8896 // Override with defaults if needed.
8897 loc = installLocationPolicy(pkgLite);
8898 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
8899 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
8900 } else if (!onSd && !onInt) {
8901 // Override install location with flags
8902 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
8903 // Set the flag to install on external media.
8904 installFlags |= PackageManager.INSTALL_EXTERNAL;
8905 installFlags &= ~PackageManager.INSTALL_INTERNAL;
8907 // Make sure the flag for installing on external
8909 installFlags |= PackageManager.INSTALL_INTERNAL;
8910 installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8916 final InstallArgs args = createInstallArgs(this);
8919 if (ret == PackageManager.INSTALL_SUCCEEDED) {
8921 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
8922 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
8924 int userIdentifier = getUser().getIdentifier();
8925 if (userIdentifier == UserHandle.USER_ALL
8926 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
8927 userIdentifier = UserHandle.USER_OWNER;
8931 * Determine if we have any installed package verifiers. If we
8932 * do, then we'll defer to them to verify the packages.
8934 final int requiredUid = mRequiredVerifierPackage == null ? -1
8935 : getPackageUid(mRequiredVerifierPackage, userIdentifier);
8936 if (!origin.existing && requiredUid != -1
8937 && isVerificationEnabled(userIdentifier, installFlags)) {
8938 final Intent verification = new Intent(
8939 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
8940 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
8942 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8944 final List<ResolveInfo> receivers = queryIntentReceivers(verification,
8945 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
8946 0 /* TODO: Which userId? */);
8949 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
8950 + verification.toString() + " with " + pkgLite.verifiers.length
8951 + " optional verifiers");
8954 final int verificationId = mPendingVerificationToken++;
8956 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8958 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
8959 installerPackageName);
8961 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
8964 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
8965 pkgLite.packageName);
8967 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
8968 pkgLite.versionCode);
8970 if (verificationParams != null) {
8971 if (verificationParams.getVerificationURI() != null) {
8972 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
8973 verificationParams.getVerificationURI());
8975 if (verificationParams.getOriginatingURI() != null) {
8976 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
8977 verificationParams.getOriginatingURI());
8979 if (verificationParams.getReferrer() != null) {
8980 verification.putExtra(Intent.EXTRA_REFERRER,
8981 verificationParams.getReferrer());
8983 if (verificationParams.getOriginatingUid() >= 0) {
8984 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
8985 verificationParams.getOriginatingUid());
8987 if (verificationParams.getInstallerUid() >= 0) {
8988 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
8989 verificationParams.getInstallerUid());
8993 final PackageVerificationState verificationState = new PackageVerificationState(
8996 mPendingVerification.append(verificationId, verificationState);
8998 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
8999 receivers, verificationState);
9002 * If any sufficient verifiers were listed in the package
9003 * manifest, attempt to ask them.
9005 if (sufficientVerifiers != null) {
9006 final int N = sufficientVerifiers.size();
9008 Slog.i(TAG, "Additional verifiers required, but none installed.");
9009 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
9011 for (int i = 0; i < N; i++) {
9012 final ComponentName verifierComponent = sufficientVerifiers.get(i);
9014 final Intent sufficientIntent = new Intent(verification);
9015 sufficientIntent.setComponent(verifierComponent);
9017 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
9022 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
9023 mRequiredVerifierPackage, receivers);
9024 if (ret == PackageManager.INSTALL_SUCCEEDED
9025 && mRequiredVerifierPackage != null) {
9027 * Send the intent to the required verification agent,
9028 * but only start the verification timeout after the
9029 * target BroadcastReceivers have run.
9031 verification.setComponent(requiredVerifierComponent);
9032 mContext.sendOrderedBroadcastAsUser(verification, getUser(),
9033 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9034 new BroadcastReceiver() {
9036 public void onReceive(Context context, Intent intent) {
9037 final Message msg = mHandler
9038 .obtainMessage(CHECK_PENDING_VERIFICATION);
9039 msg.arg1 = verificationId;
9040 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
9042 }, null, 0, null, null);
9045 * We don't want the copy to proceed until verification
9046 * succeeds, so null out this field.
9052 * No package verification is enabled, so immediately start
9053 * the remote call to initiate copy using temporary file.
9055 ret = args.copyApk(mContainerService, true);
9063 void handleReturnCode() {
9064 // If mArgs is null, then MCS couldn't be reached. When it
9065 // reconnects, it will try again to install. At that point, this
9067 if (mArgs != null) {
9068 processPendingInstall(mArgs, mRet);
9073 void handleServiceError() {
9074 mArgs = createInstallArgs(this);
9075 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9078 public boolean isForwardLocked() {
9079 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9084 * Used during creation of InstallArgs
9086 * @param installFlags package installation flags
9087 * @return true if should be installed on external storage
9089 private static boolean installOnSd(int installFlags) {
9090 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
9093 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
9100 * Used during creation of InstallArgs
9102 * @param installFlags package installation flags
9103 * @return true if should be installed as forward locked
9105 private static boolean installForwardLocked(int installFlags) {
9106 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9109 private InstallArgs createInstallArgs(InstallParams params) {
9110 if (installOnSd(params.installFlags) || params.isForwardLocked()) {
9111 return new AsecInstallArgs(params);
9113 return new FileInstallArgs(params);
9118 * Create args that describe an existing installed package. Typically used
9119 * when cleaning up old installs, or used as a move source.
9121 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
9122 String resourcePath, String nativeLibraryRoot, String[] instructionSets) {
9123 final boolean isInAsec;
9124 if (installOnSd(installFlags)) {
9125 /* Apps on SD card are always in ASEC containers. */
9127 } else if (installForwardLocked(installFlags)
9128 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
9130 * Forward-locked apps are only in ASEC containers if they're the
9139 return new AsecInstallArgs(codePath, instructionSets,
9140 installOnSd(installFlags), installForwardLocked(installFlags));
9142 return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
9147 static abstract class InstallArgs {
9148 /** @see InstallParams#origin */
9149 final OriginInfo origin;
9151 final IPackageInstallObserver2 observer;
9152 // Always refers to PackageManager flags only
9153 final int installFlags;
9154 final String installerPackageName;
9155 final ManifestDigest manifestDigest;
9156 final UserHandle user;
9157 final String abiOverride;
9159 // The list of instruction sets supported by this app. This is currently
9160 // only used during the rmdex() phase to clean up resources. We can get rid of this
9161 // if we move dex files under the common app path.
9162 /* nullable */ String[] instructionSets;
9164 InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
9165 String installerPackageName, ManifestDigest manifestDigest, UserHandle user,
9166 String[] instructionSets, String abiOverride) {
9167 this.origin = origin;
9168 this.installFlags = installFlags;
9169 this.observer = observer;
9170 this.installerPackageName = installerPackageName;
9171 this.manifestDigest = manifestDigest;
9173 this.instructionSets = instructionSets;
9174 this.abiOverride = abiOverride;
9177 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
9178 abstract int doPreInstall(int status);
9181 * Rename package into final resting place. All paths on the given
9182 * scanned package should be updated to reflect the rename.
9184 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
9185 abstract int doPostInstall(int status, int uid);
9187 /** @see PackageSettingBase#codePathString */
9188 abstract String getCodePath();
9189 /** @see PackageSettingBase#resourcePathString */
9190 abstract String getResourcePath();
9191 abstract String getLegacyNativeLibraryPath();
9193 // Need installer lock especially for dex file removal.
9194 abstract void cleanUpResourcesLI();
9195 abstract boolean doPostDeleteLI(boolean delete);
9196 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
9199 * Called before the source arguments are copied. This is used mostly
9200 * for MoveParams when it needs to read the source file to put it in the
9204 return PackageManager.INSTALL_SUCCEEDED;
9208 * Called after the source arguments are copied. This is used mostly for
9209 * MoveParams when it needs to read the source file to put it in the
9214 int doPostCopy(int uid) {
9215 return PackageManager.INSTALL_SUCCEEDED;
9218 protected boolean isFwdLocked() {
9219 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9222 protected boolean isExternal() {
9223 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
9226 UserHandle getUser() {
9232 * Logic to handle installation of non-ASEC applications, including copying
9233 * and renaming logic.
9235 class FileInstallArgs extends InstallArgs {
9236 private File codeFile;
9237 private File resourceFile;
9238 private File legacyNativeLibraryPath;
9240 // Example topology:
9241 // /data/app/com.example/base.apk
9242 // /data/app/com.example/split_foo.apk
9243 // /data/app/com.example/lib/arm/libfoo.so
9244 // /data/app/com.example/lib/arm64/libfoo.so
9245 // /data/app/com.example/dalvik/arm/base.apk@classes.dex
9248 FileInstallArgs(InstallParams params) {
9249 super(params.origin, params.observer, params.installFlags,
9250 params.installerPackageName, params.getManifestDigest(), params.getUser(),
9251 null /* instruction sets */, params.packageAbiOverride);
9252 if (isFwdLocked()) {
9253 throw new IllegalArgumentException("Forward locking only supported in ASEC");
9257 /** Existing install */
9258 FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath,
9259 String[] instructionSets) {
9260 super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null);
9261 this.codeFile = (codePath != null) ? new File(codePath) : null;
9262 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
9263 this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ?
9264 new File(legacyNativeLibraryPath) : null;
9267 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9268 final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(),
9269 isFwdLocked(), abiOverride);
9271 final StorageManager storage = StorageManager.from(mContext);
9272 return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
9275 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9276 if (origin.staged) {
9277 Slog.d(TAG, origin.file + " already staged; skipping copy");
9278 codeFile = origin.file;
9279 resourceFile = origin.file;
9280 return PackageManager.INSTALL_SUCCEEDED;
9284 final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
9286 resourceFile = tempDir;
9287 } catch (IOException e) {
9288 Slog.w(TAG, "Failed to create copy file: " + e);
9289 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9292 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
9294 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
9295 if (!FileUtils.isValidExtFilename(name)) {
9296 throw new IllegalArgumentException("Invalid filename: " + name);
9299 final File file = new File(codeFile, name);
9300 final FileDescriptor fd = Os.open(file.getAbsolutePath(),
9301 O_RDWR | O_CREAT, 0644);
9302 Os.chmod(file.getAbsolutePath(), 0644);
9303 return new ParcelFileDescriptor(fd);
9304 } catch (ErrnoException e) {
9305 throw new RemoteException("Failed to open: " + e.getMessage());
9310 int ret = PackageManager.INSTALL_SUCCEEDED;
9311 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
9312 if (ret != PackageManager.INSTALL_SUCCEEDED) {
9313 Slog.e(TAG, "Failed to copy package");
9317 final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
9318 NativeLibraryHelper.Handle handle = null;
9320 handle = NativeLibraryHelper.Handle.create(codeFile);
9321 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
9323 } catch (IOException e) {
9324 Slog.e(TAG, "Copying native libraries failed", e);
9325 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9327 IoUtils.closeQuietly(handle);
9333 int doPreInstall(int status) {
9334 if (status != PackageManager.INSTALL_SUCCEEDED) {
9340 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9341 if (status != PackageManager.INSTALL_SUCCEEDED) {
9345 final File beforeCodeFile = codeFile;
9346 final File afterCodeFile = getNextCodePath(pkg.packageName);
9348 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
9350 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
9351 } catch (ErrnoException e) {
9352 Slog.d(TAG, "Failed to rename", e);
9356 if (!SELinux.restoreconRecursive(afterCodeFile)) {
9357 Slog.d(TAG, "Failed to restorecon");
9361 // Reflect the rename internally
9362 codeFile = afterCodeFile;
9363 resourceFile = afterCodeFile;
9365 // Reflect the rename in scanned details
9366 pkg.codePath = afterCodeFile.getAbsolutePath();
9367 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9369 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9370 pkg.splitCodePaths);
9372 // Reflect the rename in app info
9373 pkg.applicationInfo.setCodePath(pkg.codePath);
9374 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9375 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9376 pkg.applicationInfo.setResourcePath(pkg.codePath);
9377 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9378 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9384 int doPostInstall(int status, int uid) {
9385 if (status != PackageManager.INSTALL_SUCCEEDED) {
9392 String getCodePath() {
9393 return (codeFile != null) ? codeFile.getAbsolutePath() : null;
9397 String getResourcePath() {
9398 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
9402 String getLegacyNativeLibraryPath() {
9403 return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null;
9406 private boolean cleanUp() {
9407 if (codeFile == null || !codeFile.exists()) {
9411 if (codeFile.isDirectory()) {
9412 FileUtils.deleteContents(codeFile);
9416 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
9417 resourceFile.delete();
9420 if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) {
9421 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) {
9422 Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath);
9424 legacyNativeLibraryPath.delete();
9430 void cleanUpResourcesLI() {
9431 // Try enumerating all code paths before deleting
9432 List<String> allCodePaths = Collections.EMPTY_LIST;
9433 if (codeFile != null && codeFile.exists()) {
9435 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9436 allCodePaths = pkg.getAllCodePaths();
9437 } catch (PackageParserException e) {
9438 // Ignored; we tried our best
9444 if (!allCodePaths.isEmpty()) {
9445 if (instructionSets == null) {
9446 throw new IllegalStateException("instructionSet == null");
9448 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9449 for (String codePath : allCodePaths) {
9450 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9451 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9453 Slog.w(TAG, "Couldn't remove dex file for package: "
9454 + " at location " + codePath + ", retcode=" + retCode);
9455 // we don't consider this to be a failure of the core package deletion
9462 boolean doPostDeleteLI(boolean delete) {
9463 // XXX err, shouldn't we respect the delete flag?
9464 cleanUpResourcesLI();
9469 private boolean isAsecExternal(String cid) {
9470 final String asecPath = PackageHelper.getSdFilesystem(cid);
9471 return !asecPath.startsWith(mAsecInternalPath);
9474 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
9475 PackageManagerException {
9477 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
9478 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
9479 throw new PackageManagerException(copyRet, message);
9485 * Extract the MountService "container ID" from the full code path of an
9488 static String cidFromCodePath(String fullCodePath) {
9489 int eidx = fullCodePath.lastIndexOf("/");
9490 String subStr1 = fullCodePath.substring(0, eidx);
9491 int sidx = subStr1.lastIndexOf("/");
9492 return subStr1.substring(sidx+1, eidx);
9496 * Logic to handle installation of ASEC applications, including copying and
9499 class AsecInstallArgs extends InstallArgs {
9500 static final String RES_FILE_NAME = "pkg.apk";
9501 static final String PUBLIC_RES_FILE_NAME = "res.zip";
9505 String resourcePath;
9506 String legacyNativeLibraryDir;
9509 AsecInstallArgs(InstallParams params) {
9510 super(params.origin, params.observer, params.installFlags,
9511 params.installerPackageName, params.getManifestDigest(),
9512 params.getUser(), null /* instruction sets */,
9513 params.packageAbiOverride);
9516 /** Existing install */
9517 AsecInstallArgs(String fullCodePath, String[] instructionSets,
9518 boolean isExternal, boolean isForwardLocked) {
9519 super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0)
9520 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9521 instructionSets, null);
9522 // Hackily pretend we're still looking at a full code path
9523 if (!fullCodePath.endsWith(RES_FILE_NAME)) {
9524 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
9527 // Extract cid from fullCodePath
9528 int eidx = fullCodePath.lastIndexOf("/");
9529 String subStr1 = fullCodePath.substring(0, eidx);
9530 int sidx = subStr1.lastIndexOf("/");
9531 cid = subStr1.substring(sidx+1, eidx);
9532 setMountPath(subStr1);
9535 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
9536 super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
9537 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9538 instructionSets, null);
9540 setMountPath(PackageHelper.getSdDir(cid));
9543 void createCopyFile() {
9544 cid = mInstallerService.allocateExternalStageCidLegacy();
9547 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9548 final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
9553 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
9555 target = Environment.getDataDirectory();
9558 final StorageManager storage = StorageManager.from(mContext);
9559 return (sizeBytes <= storage.getStorageBytesUntilLow(target));
9562 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9563 if (origin.staged) {
9564 Slog.d(TAG, origin.cid + " already staged; skipping copy");
9566 setMountPath(PackageHelper.getSdDir(cid));
9567 return PackageManager.INSTALL_SUCCEEDED;
9574 * Pre-emptively destroy the container since it's destroyed if
9575 * copying fails due to it existing anyway.
9577 PackageHelper.destroySdDir(cid);
9580 final String newMountPath = imcs.copyPackageToContainer(
9581 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
9582 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
9584 if (newMountPath != null) {
9585 setMountPath(newMountPath);
9586 return PackageManager.INSTALL_SUCCEEDED;
9588 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9593 String getCodePath() {
9598 String getResourcePath() {
9599 return resourcePath;
9603 String getLegacyNativeLibraryPath() {
9604 return legacyNativeLibraryDir;
9607 int doPreInstall(int status) {
9608 if (status != PackageManager.INSTALL_SUCCEEDED) {
9609 // Destroy container
9610 PackageHelper.destroySdDir(cid);
9612 boolean mounted = PackageHelper.isContainerMounted(cid);
9614 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
9615 Process.SYSTEM_UID);
9616 if (newMountPath != null) {
9617 setMountPath(newMountPath);
9619 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9626 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9627 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
9628 String newMountPath = null;
9629 if (PackageHelper.isContainerMounted(cid)) {
9630 // Unmount the container
9631 if (!PackageHelper.unMountSdDir(cid)) {
9632 Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
9636 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9637 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
9638 " which might be stale. Will try to clean up.");
9639 // Clean up the stale container and proceed to recreate.
9640 if (!PackageHelper.destroySdDir(newCacheId)) {
9641 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
9644 // Successfully cleaned up stale container. Try to rename again.
9645 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9646 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
9647 + " inspite of cleaning it up.");
9651 if (!PackageHelper.isContainerMounted(newCacheId)) {
9652 Slog.w(TAG, "Mounting container " + newCacheId);
9653 newMountPath = PackageHelper.mountSdDir(newCacheId,
9654 getEncryptKey(), Process.SYSTEM_UID);
9656 newMountPath = PackageHelper.getSdDir(newCacheId);
9658 if (newMountPath == null) {
9659 Slog.w(TAG, "Failed to get cache path for " + newCacheId);
9662 Log.i(TAG, "Succesfully renamed " + cid +
9663 " to " + newCacheId +
9664 " at new path: " + newMountPath);
9667 final File beforeCodeFile = new File(packagePath);
9668 setMountPath(newMountPath);
9669 final File afterCodeFile = new File(packagePath);
9671 // Reflect the rename in scanned details
9672 pkg.codePath = afterCodeFile.getAbsolutePath();
9673 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9675 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9676 pkg.splitCodePaths);
9678 // Reflect the rename in app info
9679 pkg.applicationInfo.setCodePath(pkg.codePath);
9680 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9681 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9682 pkg.applicationInfo.setResourcePath(pkg.codePath);
9683 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9684 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9689 private void setMountPath(String mountPath) {
9690 final File mountFile = new File(mountPath);
9692 final File monolithicFile = new File(mountFile, RES_FILE_NAME);
9693 if (monolithicFile.exists()) {
9694 packagePath = monolithicFile.getAbsolutePath();
9695 if (isFwdLocked()) {
9696 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
9698 resourcePath = packagePath;
9701 packagePath = mountFile.getAbsolutePath();
9702 resourcePath = packagePath;
9705 legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
9708 int doPostInstall(int status, int uid) {
9709 if (status != PackageManager.INSTALL_SUCCEEDED) {
9712 final int groupOwner;
9713 final String protectedFile;
9714 if (isFwdLocked()) {
9715 groupOwner = UserHandle.getSharedAppGid(uid);
9716 protectedFile = RES_FILE_NAME;
9719 protectedFile = null;
9722 if (uid < Process.FIRST_APPLICATION_UID
9723 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
9724 Slog.e(TAG, "Failed to finalize " + cid);
9725 PackageHelper.destroySdDir(cid);
9726 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9729 boolean mounted = PackageHelper.isContainerMounted(cid);
9731 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
9737 private void cleanUp() {
9738 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
9740 // Destroy secure container
9741 PackageHelper.destroySdDir(cid);
9744 private List<String> getAllCodePaths() {
9745 final File codeFile = new File(getCodePath());
9746 if (codeFile != null && codeFile.exists()) {
9748 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9749 return pkg.getAllCodePaths();
9750 } catch (PackageParserException e) {
9751 // Ignored; we tried our best
9754 return Collections.EMPTY_LIST;
9757 void cleanUpResourcesLI() {
9758 // Enumerate all code paths before deleting
9759 cleanUpResourcesLI(getAllCodePaths());
9762 private void cleanUpResourcesLI(List<String> allCodePaths) {
9765 if (!allCodePaths.isEmpty()) {
9766 if (instructionSets == null) {
9767 throw new IllegalStateException("instructionSet == null");
9769 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9770 for (String codePath : allCodePaths) {
9771 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9772 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9774 Slog.w(TAG, "Couldn't remove dex file for package: "
9775 + " at location " + codePath + ", retcode=" + retCode);
9776 // we don't consider this to be a failure of the core package deletion
9783 boolean matchContainer(String app) {
9784 if (cid.startsWith(app)) {
9790 String getPackageName() {
9791 return getAsecPackageName(cid);
9794 boolean doPostDeleteLI(boolean delete) {
9795 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
9796 final List<String> allCodePaths = getAllCodePaths();
9797 boolean mounted = PackageHelper.isContainerMounted(cid);
9800 if (PackageHelper.unMountSdDir(cid)) {
9804 if (!mounted && delete) {
9805 cleanUpResourcesLI(allCodePaths);
9812 if (isFwdLocked()) {
9813 if (!PackageHelper.fixSdPermissions(cid,
9814 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
9815 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9819 return PackageManager.INSTALL_SUCCEEDED;
9823 int doPostCopy(int uid) {
9824 if (isFwdLocked()) {
9825 if (uid < Process.FIRST_APPLICATION_UID
9826 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
9828 Slog.e(TAG, "Failed to finalize " + cid);
9829 PackageHelper.destroySdDir(cid);
9830 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9834 return PackageManager.INSTALL_SUCCEEDED;
9838 static String getAsecPackageName(String packageCid) {
9839 int idx = packageCid.lastIndexOf("-");
9843 return packageCid.substring(0, idx);
9846 // Utility method used to create code paths based on package name and available index.
9847 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
9850 // Fall back to default value of idx=1 if prefix is not
9851 // part of oldCodePath
9852 if (oldCodePath != null) {
9853 String subStr = oldCodePath;
9854 // Drop the suffix right away
9855 if (suffix != null && subStr.endsWith(suffix)) {
9856 subStr = subStr.substring(0, subStr.length() - suffix.length());
9858 // If oldCodePath already contains prefix find out the
9859 // ending index to either increment or decrement.
9860 int sidx = subStr.lastIndexOf(prefix);
9862 subStr = subStr.substring(sidx + prefix.length());
9863 if (subStr != null) {
9864 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
9865 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
9868 idx = Integer.parseInt(subStr);
9874 } catch(NumberFormatException e) {
9879 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
9880 return prefix + idxStr;
9883 private File getNextCodePath(String packageName) {
9887 result = new File(mAppInstallDir, packageName + "-" + suffix);
9889 } while (result.exists());
9893 // Utility method used to ignore ADD/REMOVE events
9894 // by directory observer.
9895 private static boolean ignoreCodePath(String fullPathStr) {
9896 String apkName = deriveCodePathName(fullPathStr);
9897 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
9898 if (idx != -1 && ((idx+1) < apkName.length())) {
9899 // Make sure the package ends with a numeral
9900 String version = apkName.substring(idx+1);
9902 Integer.parseInt(version);
9904 } catch (NumberFormatException e) {}
9909 // Utility method that returns the relative package path with respect
9910 // to the installation directory. Like say for /data/data/com.test-1.apk
9911 // string com.test-1 is returned.
9912 static String deriveCodePathName(String codePath) {
9913 if (codePath == null) {
9916 final File codeFile = new File(codePath);
9917 final String name = codeFile.getName();
9918 if (codeFile.isDirectory()) {
9920 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
9921 final int lastDot = name.lastIndexOf('.');
9922 return name.substring(0, lastDot);
9924 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
9929 class PackageInstalledInfo {
9932 // The set of users that originally had this package installed.
9934 // The set of users that now have this package installed.
9936 PackageParser.Package pkg;
9939 PackageRemovedInfo removedInfo;
9941 public void setError(int code, String msg) {
9947 public void setError(String msg, PackageParserException e) {
9948 returnCode = e.error;
9949 returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9950 Slog.w(TAG, msg, e);
9953 public void setError(String msg, PackageManagerException e) {
9954 returnCode = e.error;
9955 returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9956 Slog.w(TAG, msg, e);
9959 // In some error cases we want to convey more info back to the observer
9961 String origPermission;
9965 * Install a non-existing package.
9967 private void installNewPackageLI(PackageParser.Package pkg,
9968 int parseFlags, int scanFlags, UserHandle user,
9969 String installerPackageName, PackageInstalledInfo res) {
9970 // Remember this for later, in case we need to rollback this install
9971 String pkgName = pkg.packageName;
9973 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
9974 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
9975 synchronized(mPackages) {
9976 if (mSettings.mRenamedPackages.containsKey(pkgName)) {
9977 // A package with the same name is already installed, though
9978 // it has been renamed to an older name. The package we
9979 // are trying to install should be installed as an update to
9980 // the existing one, but that has not been requested, so bail.
9981 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9982 + " without first uninstalling package running as "
9983 + mSettings.mRenamedPackages.get(pkgName));
9986 if (mPackages.containsKey(pkgName)) {
9987 // Don't allow installation over an existing package with the same name.
9988 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9989 + " without first uninstalling.");
9995 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
9996 System.currentTimeMillis(), user);
9998 updateSettingsLI(newPackage, installerPackageName, null, null, res);
9999 // delete the partially installed application. the data directory will have to be
10000 // restored if it was already existing
10001 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10002 // remove package from internal structures. Note that we want deletePackageX to
10003 // delete the package data and cache directories that it created in
10004 // scanPackageLocked, unless those directories existed before we even tried to
10006 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
10007 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
10008 res.removedInfo, true);
10011 } catch (PackageManagerException e) {
10012 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10016 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
10017 // Upgrade keysets are being used. Determine if new package has a superset of the
10019 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
10020 KeySetManagerService ksms = mSettings.mKeySetManagerService;
10021 for (int i = 0; i < upgradeKeySets.length; i++) {
10022 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
10023 if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
10030 private void replacePackageLI(PackageParser.Package pkg,
10031 int parseFlags, int scanFlags, UserHandle user,
10032 String installerPackageName, PackageInstalledInfo res) {
10033 PackageParser.Package oldPackage;
10034 String pkgName = pkg.packageName;
10036 boolean[] perUserInstalled;
10038 // First find the old package info and check signatures
10039 synchronized(mPackages) {
10040 oldPackage = mPackages.get(pkgName);
10041 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
10042 PackageSetting ps = mSettings.mPackages.get(pkgName);
10043 if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10044 // default to original signature matching
10045 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
10046 != PackageManager.SIGNATURE_MATCH) {
10047 res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10048 "New package has a different signature: " + pkgName);
10052 if(!checkUpgradeKeySetLP(ps, pkg)) {
10053 res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10054 "New package not signed by keys specified by upgrade-keysets: "
10060 // In case of rollback, remember per-user/profile install state
10061 allUsers = sUserManager.getUserIds();
10062 perUserInstalled = new boolean[allUsers.length];
10063 for (int i = 0; i < allUsers.length; i++) {
10064 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10068 boolean sysPkg = (isSystemApp(oldPackage));
10070 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10071 user, allUsers, perUserInstalled, installerPackageName, res);
10073 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10074 user, allUsers, perUserInstalled, installerPackageName, res);
10078 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
10079 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10080 int[] allUsers, boolean[] perUserInstalled,
10081 String installerPackageName, PackageInstalledInfo res) {
10082 String pkgName = deletedPackage.packageName;
10083 boolean deletedPkg = true;
10084 boolean updatedSettings = false;
10086 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
10088 long origUpdateTime;
10089 if (pkg.mExtras != null) {
10090 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
10092 origUpdateTime = 0;
10095 // First delete the existing package while retaining the data directory
10096 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
10097 res.removedInfo, true)) {
10098 // If the existing package wasn't successfully deleted
10099 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
10100 deletedPkg = false;
10102 // Successfully deleted the old package; proceed with replace.
10104 // If deleted package lived in a container, give users a chance to
10105 // relinquish resources before killing.
10106 if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
10107 if (DEBUG_INSTALL) {
10108 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
10110 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
10111 final ArrayList<String> pkgList = new ArrayList<String>(1);
10112 pkgList.add(deletedPackage.applicationInfo.packageName);
10113 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
10116 deleteCodeCacheDirsLI(pkgName);
10118 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
10119 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
10120 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10121 updatedSettings = true;
10122 } catch (PackageManagerException e) {
10123 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10127 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10128 // remove package from internal structures. Note that we want deletePackageX to
10129 // delete the package data and cache directories that it created in
10130 // scanPackageLocked, unless those directories existed before we even tried to
10132 if(updatedSettings) {
10133 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
10135 pkgName, null, true, allUsers, perUserInstalled,
10136 PackageManager.DELETE_KEEP_DATA,
10137 res.removedInfo, true);
10139 // Since we failed to install the new package we need to restore the old
10140 // package that we deleted.
10142 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
10143 File restoreFile = new File(deletedPackage.codePath);
10144 // Parse old package
10145 boolean oldOnSd = isExternal(deletedPackage);
10146 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
10147 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
10148 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
10149 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
10151 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
10152 } catch (PackageManagerException e) {
10153 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
10157 // Restore of old package succeeded. Update permissions.
10159 synchronized (mPackages) {
10160 updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
10161 UPDATE_PERMISSIONS_ALL);
10162 // can downgrade to reader
10163 mSettings.writeLPr();
10165 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
10170 private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
10171 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10172 int[] allUsers, boolean[] perUserInstalled,
10173 String installerPackageName, PackageInstalledInfo res) {
10174 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
10175 + ", old=" + deletedPackage);
10176 boolean disabledSystem = false;
10177 boolean updatedSettings = false;
10178 parseFlags |= PackageParser.PARSE_IS_SYSTEM;
10179 if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
10180 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10182 String packageName = deletedPackage.packageName;
10183 if (packageName == null) {
10184 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10185 "Attempt to delete null packageName.");
10188 PackageParser.Package oldPkg;
10189 PackageSetting oldPkgSetting;
10191 synchronized (mPackages) {
10192 oldPkg = mPackages.get(packageName);
10193 oldPkgSetting = mSettings.mPackages.get(packageName);
10194 if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
10195 (oldPkgSetting == null)) {
10196 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10197 "Couldn't find package:" + packageName + " information");
10202 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
10204 res.removedInfo.uid = oldPkg.applicationInfo.uid;
10205 res.removedInfo.removedPackage = packageName;
10206 // Remove existing system package
10207 removePackageLI(oldPkgSetting, true);
10209 synchronized (mPackages) {
10210 disabledSystem = mSettings.disableSystemPackageLPw(packageName);
10211 if (!disabledSystem && deletedPackage != null) {
10212 // We didn't need to disable the .apk as a current system package,
10213 // which means we are replacing another update that is already
10214 // installed. We need to make sure to delete the older one's .apk.
10215 res.removedInfo.args = createInstallArgsForExisting(0,
10216 deletedPackage.applicationInfo.getCodePath(),
10217 deletedPackage.applicationInfo.getResourcePath(),
10218 deletedPackage.applicationInfo.nativeLibraryRootDir,
10219 getAppDexInstructionSets(deletedPackage.applicationInfo));
10221 res.removedInfo.args = null;
10225 // Successfully disabled the old package. Now proceed with re-installation
10226 deleteCodeCacheDirsLI(packageName);
10228 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10229 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10231 PackageParser.Package newPackage = null;
10233 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
10234 if (newPackage.mExtras != null) {
10235 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
10236 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
10237 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
10239 // is the update attempting to change shared user? that isn't going to work...
10240 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
10241 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
10242 "Forbidding shared user change from " + oldPkgSetting.sharedUser
10243 + " to " + newPkgSetting.sharedUser);
10244 updatedSettings = true;
10248 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10249 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10250 updatedSettings = true;
10253 } catch (PackageManagerException e) {
10254 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10257 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10258 // Re installation failed. Restore old information
10259 // Remove new pkg information
10260 if (newPackage != null) {
10261 removeInstalledPackageLI(newPackage, true);
10263 // Add back the old system package
10265 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
10266 } catch (PackageManagerException e) {
10267 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
10269 // Restore the old system information in Settings
10270 synchronized (mPackages) {
10271 if (disabledSystem) {
10272 mSettings.enableSystemPackageLPw(packageName);
10274 if (updatedSettings) {
10275 mSettings.setInstallerPackageName(packageName,
10276 oldPkgSetting.installerPackageName);
10278 mSettings.writeLPr();
10283 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
10284 int[] allUsers, boolean[] perUserInstalled,
10285 PackageInstalledInfo res) {
10286 String pkgName = newPackage.packageName;
10287 synchronized (mPackages) {
10288 //write settings. the installStatus will be incomplete at this stage.
10289 //note that the new package setting would have already been
10290 //added to mPackages. It hasn't been persisted yet.
10291 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
10292 mSettings.writeLPr();
10295 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
10297 synchronized (mPackages) {
10298 updatePermissionsLPw(newPackage.packageName, newPackage,
10299 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
10300 ? UPDATE_PERMISSIONS_ALL : 0));
10301 // For system-bundled packages, we assume that installing an upgraded version
10302 // of the package implies that the user actually wants to run that new code,
10303 // so we enable the package.
10304 if (isSystemApp(newPackage)) {
10305 // NB: implicit assumption that system package upgrades apply to all users
10306 if (DEBUG_INSTALL) {
10307 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
10309 PackageSetting ps = mSettings.mPackages.get(pkgName);
10311 if (res.origUsers != null) {
10312 for (int userHandle : res.origUsers) {
10313 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
10314 userHandle, installerPackageName);
10317 // Also convey the prior install/uninstall state
10318 if (allUsers != null && perUserInstalled != null) {
10319 for (int i = 0; i < allUsers.length; i++) {
10320 if (DEBUG_INSTALL) {
10321 Slog.d(TAG, " user " + allUsers[i]
10322 + " => " + perUserInstalled[i]);
10324 ps.setInstalled(perUserInstalled[i], allUsers[i]);
10326 // these install state changes will be persisted in the
10327 // upcoming call to mSettings.writeLPr().
10331 res.name = pkgName;
10332 res.uid = newPackage.applicationInfo.uid;
10333 res.pkg = newPackage;
10334 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
10335 mSettings.setInstallerPackageName(pkgName, installerPackageName);
10336 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10337 //to update install status
10338 mSettings.writeLPr();
10342 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
10343 final int installFlags = args.installFlags;
10344 String installerPackageName = args.installerPackageName;
10345 File tmpPackageFile = new File(args.getCodePath());
10346 boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
10347 boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
10348 boolean replace = false;
10349 final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
10350 // Result object to be returned
10351 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10353 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
10354 // Retrieve PackageSettings and parse package
10355 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
10356 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
10357 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
10358 PackageParser pp = new PackageParser();
10359 pp.setSeparateProcesses(mSeparateProcesses);
10360 pp.setDisplayMetrics(mMetrics);
10362 final PackageParser.Package pkg;
10364 pkg = pp.parsePackage(tmpPackageFile, parseFlags);
10365 } catch (PackageParserException e) {
10366 res.setError("Failed parse during installPackageLI", e);
10370 // Mark that we have an install time CPU ABI override.
10371 pkg.cpuAbiOverride = args.abiOverride;
10373 String pkgName = res.name = pkg.packageName;
10374 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
10375 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
10376 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
10382 pp.collectCertificates(pkg, parseFlags);
10383 pp.collectManifestDigest(pkg);
10384 } catch (PackageParserException e) {
10385 res.setError("Failed collect during installPackageLI", e);
10389 /* If the installer passed in a manifest digest, compare it now. */
10390 if (args.manifestDigest != null) {
10391 if (DEBUG_INSTALL) {
10392 final String parsedManifest = pkg.manifestDigest == null ? "null"
10393 : pkg.manifestDigest.toString();
10394 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
10398 if (!args.manifestDigest.equals(pkg.manifestDigest)) {
10399 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
10402 } else if (DEBUG_INSTALL) {
10403 final String parsedManifest = pkg.manifestDigest == null
10404 ? "null" : pkg.manifestDigest.toString();
10405 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
10408 // Get rid of all references to package scan path via parser.
10410 String oldCodePath = null;
10411 boolean systemApp = false;
10412 synchronized (mPackages) {
10413 // Check if installing already existing package
10414 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10415 String oldName = mSettings.mRenamedPackages.get(pkgName);
10416 if (pkg.mOriginalPackages != null
10417 && pkg.mOriginalPackages.contains(oldName)
10418 && mPackages.containsKey(oldName)) {
10419 // This package is derived from an original package,
10420 // and this device has been updating from that original
10421 // name. We must continue using the original name, so
10422 // rename the new package here.
10423 pkg.setPackageName(oldName);
10424 pkgName = pkg.packageName;
10426 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
10427 + oldName + " pkgName=" + pkgName);
10428 } else if (mPackages.containsKey(pkgName)) {
10429 // This package, under its official name, already exists
10430 // on the device; we should replace it.
10432 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
10436 PackageSetting ps = mSettings.mPackages.get(pkgName);
10438 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
10440 // Quick sanity check that we're signed correctly if updating;
10441 // we'll check this again later when scanning, but we want to
10442 // bail early here before tripping over redefined permissions.
10443 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10445 verifySignaturesLP(ps, pkg);
10446 } catch (PackageManagerException e) {
10447 res.setError(e.error, e.getMessage());
10451 if (!checkUpgradeKeySetLP(ps, pkg)) {
10452 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
10453 + pkg.packageName + " upgrade keys do not match the "
10454 + "previously installed version");
10459 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
10460 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
10461 systemApp = (ps.pkg.applicationInfo.flags &
10462 ApplicationInfo.FLAG_SYSTEM) != 0;
10464 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10467 // Check whether the newly-scanned package wants to define an already-defined perm
10468 int N = pkg.permissions.size();
10469 for (int i = N-1; i >= 0; i--) {
10470 PackageParser.Permission perm = pkg.permissions.get(i);
10471 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
10473 // If the defining package is signed with our cert, it's okay. This
10474 // also includes the "updating the same package" case, of course.
10475 // "updating same package" could also involve key-rotation.
10476 final boolean sigsOk;
10477 if (!bp.sourcePackage.equals(pkg.packageName)
10478 || !(bp.packageSetting instanceof PackageSetting)
10479 || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
10480 || ((PackageSetting) bp.packageSetting).sharedUser != null) {
10481 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
10482 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
10484 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
10487 // If the owning package is the system itself, we log but allow
10488 // install to proceed; we fail the install on all other permission
10490 if (!bp.sourcePackage.equals("android")) {
10491 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
10492 + pkg.packageName + " attempting to redeclare permission "
10493 + perm.info.name + " already owned by " + bp.sourcePackage);
10494 res.origPermission = perm.info.name;
10495 res.origPackage = bp.sourcePackage;
10498 Slog.w(TAG, "Package " + pkg.packageName
10499 + " attempting to redeclare system permission "
10500 + perm.info.name + "; ignoring new declaration");
10501 pkg.permissions.remove(i);
10509 if (systemApp && onSd) {
10510 // Disable updates to system apps on sdcard
10511 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10512 "Cannot install updates to system apps on sdcard");
10516 if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
10517 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
10522 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
10523 installerPackageName, res);
10525 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
10526 args.user, installerPackageName, res);
10528 synchronized (mPackages) {
10529 final PackageSetting ps = mSettings.mPackages.get(pkgName);
10531 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10536 private static boolean isForwardLocked(PackageParser.Package pkg) {
10537 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10540 private static boolean isForwardLocked(ApplicationInfo info) {
10541 return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10544 private boolean isForwardLocked(PackageSetting ps) {
10545 return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10548 private static boolean isMultiArch(PackageSetting ps) {
10549 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10552 private static boolean isMultiArch(ApplicationInfo info) {
10553 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10556 private static boolean isExternal(PackageParser.Package pkg) {
10557 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10560 private static boolean isExternal(PackageSetting ps) {
10561 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10564 private static boolean isExternal(ApplicationInfo info) {
10565 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10568 private static boolean isSystemApp(PackageParser.Package pkg) {
10569 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10572 private static boolean isPrivilegedApp(PackageParser.Package pkg) {
10573 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
10576 private static boolean isSystemApp(ApplicationInfo info) {
10577 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10580 private static boolean isSystemApp(PackageSetting ps) {
10581 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
10584 private static boolean isUpdatedSystemApp(PackageSetting ps) {
10585 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10588 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
10589 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10592 private static boolean isUpdatedSystemApp(ApplicationInfo info) {
10593 return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10596 private int packageFlagsToInstallFlags(PackageSetting ps) {
10597 int installFlags = 0;
10598 if (isExternal(ps)) {
10599 installFlags |= PackageManager.INSTALL_EXTERNAL;
10601 if (isForwardLocked(ps)) {
10602 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10604 return installFlags;
10607 private void deleteTempPackageFiles() {
10608 final FilenameFilter filter = new FilenameFilter() {
10609 public boolean accept(File dir, String name) {
10610 return name.startsWith("vmdl") && name.endsWith(".tmp");
10613 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
10619 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
10621 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
10626 public void deletePackage(final String packageName,
10627 final IPackageDeleteObserver2 observer, final int userId, final int flags) {
10628 mContext.enforceCallingOrSelfPermission(
10629 android.Manifest.permission.DELETE_PACKAGES, null);
10630 final int uid = Binder.getCallingUid();
10631 if (UserHandle.getUserId(uid) != userId) {
10632 mContext.enforceCallingPermission(
10633 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10634 "deletePackage for user " + userId);
10636 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
10638 observer.onPackageDeleted(packageName,
10639 PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
10640 } catch (RemoteException re) {
10645 boolean uninstallBlocked = false;
10646 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
10647 int[] users = sUserManager.getUserIds();
10648 for (int i = 0; i < users.length; ++i) {
10649 if (getBlockUninstallForUser(packageName, users[i])) {
10650 uninstallBlocked = true;
10655 uninstallBlocked = getBlockUninstallForUser(packageName, userId);
10657 if (uninstallBlocked) {
10659 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
10661 } catch (RemoteException re) {
10666 if (DEBUG_REMOVE) {
10667 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
10669 // Queue up an async operation since the package deletion may take a little while.
10670 mHandler.post(new Runnable() {
10671 public void run() {
10672 mHandler.removeCallbacks(this);
10673 final int returnCode = deletePackageX(packageName, userId, flags);
10674 if (observer != null) {
10676 observer.onPackageDeleted(packageName, returnCode, null);
10677 } catch (RemoteException e) {
10678 Log.i(TAG, "Observer no longer exists.");
10685 private boolean isPackageDeviceAdmin(String packageName, int userId) {
10686 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
10687 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
10690 if (dpm.isDeviceOwner(packageName)) {
10694 if (userId == UserHandle.USER_ALL) {
10695 users = sUserManager.getUserIds();
10697 users = new int[]{userId};
10699 for (int i = 0; i < users.length; ++i) {
10700 if (dpm.packageHasActiveAdmins(packageName, users[i])) {
10705 } catch (RemoteException e) {
10711 * This method is an internal method that could be get invoked either
10712 * to delete an installed package or to clean up a failed installation.
10713 * After deleting an installed package, a broadcast is sent to notify any
10714 * listeners that the package has been installed. For cleaning up a failed
10715 * installation, the broadcast is not necessary since the package's
10716 * installation wouldn't have sent the initial broadcast either
10717 * The key steps in deleting a package are
10718 * deleting the package information in internal structures like mPackages,
10719 * deleting the packages base directories through installd
10720 * updating mSettings to reflect current status
10721 * persisting settings for later use
10722 * sending a broadcast if necessary
10724 private int deletePackageX(String packageName, int userId, int flags) {
10725 final PackageRemovedInfo info = new PackageRemovedInfo();
10728 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
10729 ? UserHandle.ALL : new UserHandle(userId);
10731 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
10732 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
10733 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
10736 boolean removedForAllUsers = false;
10737 boolean systemUpdate = false;
10739 // for the uninstall-updates case and restricted profiles, remember the per-
10740 // userhandle installed state
10742 boolean[] perUserInstalled;
10743 synchronized (mPackages) {
10744 PackageSetting ps = mSettings.mPackages.get(packageName);
10745 allUsers = sUserManager.getUserIds();
10746 perUserInstalled = new boolean[allUsers.length];
10747 for (int i = 0; i < allUsers.length; i++) {
10748 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10752 synchronized (mInstallLock) {
10753 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
10754 res = deletePackageLI(packageName, removeForUser,
10755 true, allUsers, perUserInstalled,
10756 flags | REMOVE_CHATTY, info, true);
10757 systemUpdate = info.isRemovedPackageSystemUpdate;
10758 if (res && !systemUpdate && mPackages.get(packageName) == null) {
10759 removedForAllUsers = true;
10761 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
10762 + " removedForAllUsers=" + removedForAllUsers);
10766 info.sendBroadcast(true, systemUpdate, removedForAllUsers);
10768 // If the removed package was a system update, the old system package
10769 // was re-enabled; we need to broadcast this information
10770 if (systemUpdate) {
10771 Bundle extras = new Bundle(1);
10772 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
10773 ? info.removedAppId : info.uid);
10774 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10776 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
10777 extras, null, null, null);
10778 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
10779 extras, null, null, null);
10780 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
10781 null, packageName, null, null);
10784 // Force a gc here.
10785 Runtime.getRuntime().gc();
10786 // Delete the resources here after sending the broadcast to let
10787 // other processes clean up before deleting resources.
10788 if (info.args != null) {
10789 synchronized (mInstallLock) {
10790 info.args.doPostDeleteLI(true);
10794 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
10797 static class PackageRemovedInfo {
10798 String removedPackage;
10800 int removedAppId = -1;
10801 int[] removedUsers = null;
10802 boolean isRemovedPackageSystemUpdate = false;
10803 // Clean up resources deleted packages.
10804 InstallArgs args = null;
10806 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
10807 Bundle extras = new Bundle(1);
10808 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
10809 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
10811 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10813 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
10814 if (removedPackage != null) {
10815 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
10816 extras, null, null, removedUsers);
10817 if (fullRemove && !replacing) {
10818 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
10819 extras, null, null, removedUsers);
10822 if (removedAppId >= 0) {
10823 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
10830 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
10831 * flag is not set, the data directory is removed as well.
10832 * make sure this flag is set for partially installed apps. If not its meaningless to
10833 * delete a partially installed application.
10835 private void removePackageDataLI(PackageSetting ps,
10836 int[] allUserHandles, boolean[] perUserInstalled,
10837 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
10838 String packageName = ps.name;
10839 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
10840 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
10841 // Retrieve object to delete permissions for shared user later on
10842 final PackageSetting deletedPs;
10844 synchronized (mPackages) {
10845 deletedPs = mSettings.mPackages.get(packageName);
10846 if (outInfo != null) {
10847 outInfo.removedPackage = packageName;
10848 outInfo.removedUsers = deletedPs != null
10849 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
10853 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10854 removeDataDirsLI(packageName);
10855 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
10858 synchronized (mPackages) {
10859 if (deletedPs != null) {
10860 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10861 if (outInfo != null) {
10862 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
10863 outInfo.removedAppId = mSettings.removePackageLPw(packageName);
10865 if (deletedPs != null) {
10866 updatePermissionsLPw(deletedPs.name, null, 0);
10867 if (deletedPs.sharedUser != null) {
10868 // remove permissions associated with package
10869 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
10872 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
10874 // make sure to preserve per-user disabled state if this removal was just
10875 // a downgrade of a system app to the factory package
10876 if (allUserHandles != null && perUserInstalled != null) {
10877 if (DEBUG_REMOVE) {
10878 Slog.d(TAG, "Propagating install state across downgrade");
10880 for (int i = 0; i < allUserHandles.length; i++) {
10881 if (DEBUG_REMOVE) {
10882 Slog.d(TAG, " user " + allUserHandles[i]
10883 + " => " + perUserInstalled[i]);
10885 ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10889 // can downgrade to reader
10890 if (writeSettings) {
10891 // Save settings now
10892 mSettings.writeLPr();
10895 if (outInfo != null) {
10896 // A user ID was deleted here. Go through all users and remove it
10898 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
10902 static boolean locationIsPrivileged(File path) {
10904 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
10905 .getCanonicalPath();
10906 return path.getCanonicalPath().startsWith(privilegedAppDir);
10907 } catch (IOException e) {
10908 Slog.e(TAG, "Unable to access code path " + path);
10914 * Tries to delete system package.
10916 private boolean deleteSystemPackageLI(PackageSetting newPs,
10917 int[] allUserHandles, boolean[] perUserInstalled,
10918 int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
10919 final boolean applyUserRestrictions
10920 = (allUserHandles != null) && (perUserInstalled != null);
10921 PackageSetting disabledPs = null;
10922 // Confirm if the system package has been updated
10923 // An updated system app can be deleted. This will also have to restore
10924 // the system pkg from system partition
10926 synchronized (mPackages) {
10927 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
10929 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
10930 + " disabledPs=" + disabledPs);
10931 if (disabledPs == null) {
10932 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
10934 } else if (DEBUG_REMOVE) {
10935 Slog.d(TAG, "Deleting system pkg from data partition");
10937 if (DEBUG_REMOVE) {
10938 if (applyUserRestrictions) {
10939 Slog.d(TAG, "Remembering install states:");
10940 for (int i = 0; i < allUserHandles.length; i++) {
10941 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
10945 // Delete the updated package
10946 outInfo.isRemovedPackageSystemUpdate = true;
10947 if (disabledPs.versionCode < newPs.versionCode) {
10948 // Delete data for downgrades
10949 flags &= ~PackageManager.DELETE_KEEP_DATA;
10951 // Preserve data by setting flag
10952 flags |= PackageManager.DELETE_KEEP_DATA;
10954 boolean ret = deleteInstalledPackageLI(newPs, true, flags,
10955 allUserHandles, perUserInstalled, outInfo, writeSettings);
10960 synchronized (mPackages) {
10961 // Reinstate the old system package
10962 mSettings.enableSystemPackageLPw(newPs.name);
10963 // Remove any native libraries from the upgraded package.
10964 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
10966 // Install the system package
10967 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
10968 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
10969 if (locationIsPrivileged(disabledPs.codePath)) {
10970 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10973 final PackageParser.Package newPkg;
10975 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
10976 } catch (PackageManagerException e) {
10977 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
10982 synchronized (mPackages) {
10983 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
10984 updatePermissionsLPw(newPkg.packageName, newPkg,
10985 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
10986 if (applyUserRestrictions) {
10987 if (DEBUG_REMOVE) {
10988 Slog.d(TAG, "Propagating install state across reinstall");
10990 for (int i = 0; i < allUserHandles.length; i++) {
10991 if (DEBUG_REMOVE) {
10992 Slog.d(TAG, " user " + allUserHandles[i]
10993 + " => " + perUserInstalled[i]);
10995 ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10997 // Regardless of writeSettings we need to ensure that this restriction
10998 // state propagation is persisted
10999 mSettings.writeAllUsersPackageRestrictionsLPr();
11001 // can downgrade to reader here
11002 if (writeSettings) {
11003 mSettings.writeLPr();
11009 private boolean deleteInstalledPackageLI(PackageSetting ps,
11010 boolean deleteCodeAndResources, int flags,
11011 int[] allUserHandles, boolean[] perUserInstalled,
11012 PackageRemovedInfo outInfo, boolean writeSettings) {
11013 if (outInfo != null) {
11014 outInfo.uid = ps.appId;
11017 // Delete package data from internal structures and also remove data if flag is set
11018 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
11020 // Delete application code and resources
11021 if (deleteCodeAndResources && (outInfo != null)) {
11022 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
11023 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
11024 getAppDexInstructionSets(ps));
11025 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
11031 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
11033 mContext.enforceCallingOrSelfPermission(
11034 android.Manifest.permission.DELETE_PACKAGES, null);
11035 synchronized (mPackages) {
11036 PackageSetting ps = mSettings.mPackages.get(packageName);
11038 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
11041 if (!ps.getInstalled(userId)) {
11042 // Can't block uninstall for an app that is not installed or enabled.
11043 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
11046 ps.setBlockUninstall(blockUninstall, userId);
11047 mSettings.writePackageRestrictionsLPr(userId);
11053 public boolean getBlockUninstallForUser(String packageName, int userId) {
11054 synchronized (mPackages) {
11055 PackageSetting ps = mSettings.mPackages.get(packageName);
11057 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
11060 return ps.getBlockUninstall(userId);
11065 * This method handles package deletion in general
11067 private boolean deletePackageLI(String packageName, UserHandle user,
11068 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
11069 int flags, PackageRemovedInfo outInfo,
11070 boolean writeSettings) {
11071 if (packageName == null) {
11072 Slog.w(TAG, "Attempt to delete null packageName.");
11075 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
11077 boolean dataOnly = false;
11078 int removeUser = -1;
11080 synchronized (mPackages) {
11081 ps = mSettings.mPackages.get(packageName);
11083 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11086 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
11087 && user.getIdentifier() != UserHandle.USER_ALL) {
11088 // The caller is asking that the package only be deleted for a single
11089 // user. To do this, we just mark its uninstalled state and delete
11090 // its data. If this is a system app, we only allow this to happen if
11091 // they have set the special DELETE_SYSTEM_APP which requests different
11092 // semantics than normal for uninstalling system apps.
11093 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
11094 ps.setUserState(user.getIdentifier(),
11095 COMPONENT_ENABLED_STATE_DEFAULT,
11098 true, //notLaunched
11101 false // blockUninstall
11103 if (!isSystemApp(ps)) {
11104 if (ps.isAnyInstalled(sUserManager.getUserIds())) {
11105 // Other user still have this package installed, so all
11106 // we need to do is clear this user's data and save that
11107 // it is uninstalled.
11108 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
11109 removeUser = user.getIdentifier();
11111 mSettings.writePackageRestrictionsLPr(removeUser);
11113 // We need to set it back to 'installed' so the uninstall
11114 // broadcasts will be sent correctly.
11115 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
11116 ps.setInstalled(true, user.getIdentifier());
11119 // This is a system app, so we assume that the
11120 // other users still have this package installed, so all
11121 // we need to do is clear this user's data and save that
11122 // it is uninstalled.
11123 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
11124 removeUser = user.getIdentifier();
11126 mSettings.writePackageRestrictionsLPr(removeUser);
11131 if (removeUser >= 0) {
11132 // From above, we determined that we are deleting this only
11133 // for a single user. Continue the work here.
11134 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
11135 if (outInfo != null) {
11136 outInfo.removedPackage = packageName;
11137 outInfo.removedAppId = appId;
11138 outInfo.removedUsers = new int[] {removeUser};
11140 mInstaller.clearUserData(packageName, removeUser);
11141 removeKeystoreDataIfNeeded(removeUser, appId);
11142 schedulePackageCleaning(packageName, removeUser, false);
11147 // Delete application data first
11148 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
11149 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
11153 boolean ret = false;
11154 if (isSystemApp(ps)) {
11155 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
11156 // When an updated system application is deleted we delete the existing resources as well and
11157 // fall back to existing code in system partition
11158 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
11159 flags, outInfo, writeSettings);
11161 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
11162 // Kill application pre-emptively especially for apps on sd.
11163 killApplication(packageName, ps.appId, "uninstall pkg");
11164 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
11165 allUserHandles, perUserInstalled,
11166 outInfo, writeSettings);
11172 private final class ClearStorageConnection implements ServiceConnection {
11173 IMediaContainerService mContainerService;
11176 public void onServiceConnected(ComponentName name, IBinder service) {
11177 synchronized (this) {
11178 mContainerService = IMediaContainerService.Stub.asInterface(service);
11184 public void onServiceDisconnected(ComponentName name) {
11188 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
11189 final boolean mounted;
11190 if (Environment.isExternalStorageEmulated()) {
11193 final String status = Environment.getExternalStorageState();
11195 mounted = status.equals(Environment.MEDIA_MOUNTED)
11196 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
11203 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
11205 if (userId == UserHandle.USER_ALL) {
11206 users = sUserManager.getUserIds();
11208 users = new int[] { userId };
11210 final ClearStorageConnection conn = new ClearStorageConnection();
11211 if (mContext.bindServiceAsUser(
11212 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
11214 for (int curUser : users) {
11215 long timeout = SystemClock.uptimeMillis() + 5000;
11216 synchronized (conn) {
11217 long now = SystemClock.uptimeMillis();
11218 while (conn.mContainerService == null && now < timeout) {
11220 conn.wait(timeout - now);
11221 } catch (InterruptedException e) {
11225 if (conn.mContainerService == null) {
11229 final UserEnvironment userEnv = new UserEnvironment(curUser);
11230 clearDirectory(conn.mContainerService,
11231 userEnv.buildExternalStorageAppCacheDirs(packageName));
11233 clearDirectory(conn.mContainerService,
11234 userEnv.buildExternalStorageAppDataDirs(packageName));
11235 clearDirectory(conn.mContainerService,
11236 userEnv.buildExternalStorageAppMediaDirs(packageName));
11240 mContext.unbindService(conn);
11246 public void clearApplicationUserData(final String packageName,
11247 final IPackageDataObserver observer, final int userId) {
11248 mContext.enforceCallingOrSelfPermission(
11249 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
11250 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
11251 // Queue up an async operation since the package deletion may take a little while.
11252 mHandler.post(new Runnable() {
11253 public void run() {
11254 mHandler.removeCallbacks(this);
11255 final boolean succeeded;
11256 synchronized (mInstallLock) {
11257 succeeded = clearApplicationUserDataLI(packageName, userId);
11259 clearExternalStorageDataSync(packageName, userId, true);
11261 // invoke DeviceStorageMonitor's update method to clear any notifications
11262 DeviceStorageMonitorInternal
11263 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
11268 if(observer != null) {
11270 observer.onRemoveCompleted(packageName, succeeded);
11271 } catch (RemoteException e) {
11272 Log.i(TAG, "Observer no longer exists.");
11274 } //end if observer
11279 private boolean clearApplicationUserDataLI(String packageName, int userId) {
11280 if (packageName == null) {
11281 Slog.w(TAG, "Attempt to delete null packageName.");
11285 // Try finding details about the requested package
11286 PackageParser.Package pkg;
11287 synchronized (mPackages) {
11288 pkg = mPackages.get(packageName);
11290 final PackageSetting ps = mSettings.mPackages.get(packageName);
11298 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11301 // Always delete data directories for package, even if we found no other
11302 // record of app. This helps users recover from UID mismatches without
11303 // resorting to a full data wipe.
11304 int retCode = mInstaller.clearUserData(packageName, userId);
11306 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
11314 if (pkg != null && pkg.applicationInfo != null) {
11315 final int appId = pkg.applicationInfo.uid;
11316 removeKeystoreDataIfNeeded(userId, appId);
11319 // Create a native library symlink only if we have native libraries
11320 // and if the native libraries are 32 bit libraries. We do not provide
11321 // this symlink for 64 bit libraries.
11322 if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
11323 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
11324 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
11325 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
11326 Slog.w(TAG, "Failed linking native library dir");
11335 * Remove entries from the keystore daemon. Will only remove it if the
11336 * {@code appId} is valid.
11338 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
11343 final KeyStore keyStore = KeyStore.getInstance();
11344 if (keyStore != null) {
11345 if (userId == UserHandle.USER_ALL) {
11346 for (final int individual : sUserManager.getUserIds()) {
11347 keyStore.clearUid(UserHandle.getUid(individual, appId));
11350 keyStore.clearUid(UserHandle.getUid(userId, appId));
11353 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
11358 public void deleteApplicationCacheFiles(final String packageName,
11359 final IPackageDataObserver observer) {
11360 mContext.enforceCallingOrSelfPermission(
11361 android.Manifest.permission.DELETE_CACHE_FILES, null);
11362 // Queue up an async operation since the package deletion may take a little while.
11363 final int userId = UserHandle.getCallingUserId();
11364 mHandler.post(new Runnable() {
11365 public void run() {
11366 mHandler.removeCallbacks(this);
11367 final boolean succeded;
11368 synchronized (mInstallLock) {
11369 succeded = deleteApplicationCacheFilesLI(packageName, userId);
11371 clearExternalStorageDataSync(packageName, userId, false);
11372 if(observer != null) {
11374 observer.onRemoveCompleted(packageName, succeded);
11375 } catch (RemoteException e) {
11376 Log.i(TAG, "Observer no longer exists.");
11378 } //end if observer
11383 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
11384 if (packageName == null) {
11385 Slog.w(TAG, "Attempt to delete null packageName.");
11388 PackageParser.Package p;
11389 synchronized (mPackages) {
11390 p = mPackages.get(packageName);
11393 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11396 final ApplicationInfo applicationInfo = p.applicationInfo;
11397 if (applicationInfo == null) {
11398 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11401 int retCode = mInstaller.deleteCacheFiles(packageName, userId);
11403 Slog.w(TAG, "Couldn't remove cache files for package: "
11404 + packageName + " u" + userId);
11411 public void getPackageSizeInfo(final String packageName, int userHandle,
11412 final IPackageStatsObserver observer) {
11413 mContext.enforceCallingOrSelfPermission(
11414 android.Manifest.permission.GET_PACKAGE_SIZE, null);
11415 if (packageName == null) {
11416 throw new IllegalArgumentException("Attempt to get size of null packageName");
11419 PackageStats stats = new PackageStats(packageName, userHandle);
11422 * Queue up an async operation since the package measurement may take a
11425 Message msg = mHandler.obtainMessage(INIT_COPY);
11426 msg.obj = new MeasureParams(stats, observer);
11427 mHandler.sendMessage(msg);
11430 private boolean getPackageSizeInfoLI(String packageName, int userHandle,
11431 PackageStats pStats) {
11432 if (packageName == null) {
11433 Slog.w(TAG, "Attempt to get size of null packageName.");
11436 PackageParser.Package p;
11437 boolean dataOnly = false;
11438 String libDirRoot = null;
11439 String asecPath = null;
11440 PackageSetting ps = null;
11441 synchronized (mPackages) {
11442 p = mPackages.get(packageName);
11443 ps = mSettings.mPackages.get(packageName);
11446 if((ps == null) || (ps.pkg == null)) {
11447 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11453 libDirRoot = ps.legacyNativeLibraryPathString;
11455 if (p != null && (isExternal(p) || isForwardLocked(p))) {
11456 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
11457 if (secureContainerId != null) {
11458 asecPath = PackageHelper.getSdFilesystem(secureContainerId);
11462 String publicSrcDir = null;
11464 final ApplicationInfo applicationInfo = p.applicationInfo;
11465 if (applicationInfo == null) {
11466 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11469 if (isForwardLocked(p)) {
11470 publicSrcDir = applicationInfo.getBaseResourcePath();
11473 // TODO: extend to measure size of split APKs
11474 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
11475 // not just the first level.
11476 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
11477 // just the primary.
11478 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
11479 int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
11480 publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
11485 // Fix-up for forward-locked applications in ASEC containers.
11486 if (!isExternal(p)) {
11487 pStats.codeSize += pStats.externalCodeSize;
11488 pStats.externalCodeSize = 0L;
11496 public void addPackageToPreferred(String packageName) {
11497 Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
11501 public void removePackageFromPreferred(String packageName) {
11502 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
11506 public List<PackageInfo> getPreferredPackages(int flags) {
11507 return new ArrayList<PackageInfo>();
11510 private int getUidTargetSdkVersionLockedLPr(int uid) {
11511 Object obj = mSettings.getUserIdLPr(uid);
11512 if (obj instanceof SharedUserSetting) {
11513 final SharedUserSetting sus = (SharedUserSetting) obj;
11514 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
11515 final Iterator<PackageSetting> it = sus.packages.iterator();
11516 while (it.hasNext()) {
11517 final PackageSetting ps = it.next();
11518 if (ps.pkg != null) {
11519 int v = ps.pkg.applicationInfo.targetSdkVersion;
11520 if (v < vers) vers = v;
11524 } else if (obj instanceof PackageSetting) {
11525 final PackageSetting ps = (PackageSetting) obj;
11526 if (ps.pkg != null) {
11527 return ps.pkg.applicationInfo.targetSdkVersion;
11530 return Build.VERSION_CODES.CUR_DEVELOPMENT;
11534 public void addPreferredActivity(IntentFilter filter, int match,
11535 ComponentName[] set, ComponentName activity, int userId) {
11536 addPreferredActivityInternal(filter, match, set, activity, true, userId,
11537 "Adding preferred");
11540 private void addPreferredActivityInternal(IntentFilter filter, int match,
11541 ComponentName[] set, ComponentName activity, boolean always, int userId,
11544 int callingUid = Binder.getCallingUid();
11545 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
11546 if (filter.countActions() == 0) {
11547 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11550 synchronized (mPackages) {
11551 if (mContext.checkCallingOrSelfPermission(
11552 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11553 != PackageManager.PERMISSION_GRANTED) {
11554 if (getUidTargetSdkVersionLockedLPr(callingUid)
11555 < Build.VERSION_CODES.FROYO) {
11556 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
11560 mContext.enforceCallingOrSelfPermission(
11561 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11564 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
11565 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
11567 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11568 pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
11569 scheduleWritePackageRestrictionsLocked(userId);
11574 public void replacePreferredActivity(IntentFilter filter, int match,
11575 ComponentName[] set, ComponentName activity, int userId) {
11576 if (filter.countActions() != 1) {
11577 throw new IllegalArgumentException(
11578 "replacePreferredActivity expects filter to have only 1 action.");
11580 if (filter.countDataAuthorities() != 0
11581 || filter.countDataPaths() != 0
11582 || filter.countDataSchemes() > 1
11583 || filter.countDataTypes() != 0) {
11584 throw new IllegalArgumentException(
11585 "replacePreferredActivity expects filter to have no data authorities, " +
11586 "paths, or types; and at most one scheme.");
11589 final int callingUid = Binder.getCallingUid();
11590 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
11591 synchronized (mPackages) {
11592 if (mContext.checkCallingOrSelfPermission(
11593 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11594 != PackageManager.PERMISSION_GRANTED) {
11595 if (getUidTargetSdkVersionLockedLPr(callingUid)
11596 < Build.VERSION_CODES.FROYO) {
11597 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
11598 + Binder.getCallingUid());
11601 mContext.enforceCallingOrSelfPermission(
11602 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11605 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11607 // Get all of the existing entries that exactly match this filter.
11608 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
11609 if (existing != null && existing.size() == 1) {
11610 PreferredActivity cur = existing.get(0);
11611 if (DEBUG_PREFERRED) {
11612 Slog.i(TAG, "Checking replace of preferred:");
11613 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11614 if (!cur.mPref.mAlways) {
11615 Slog.i(TAG, " -- CUR; not mAlways!");
11617 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch);
11618 Slog.i(TAG, " -- CUR: mSet="
11619 + Arrays.toString(cur.mPref.mSetComponents));
11620 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent);
11621 Slog.i(TAG, " -- NEW: mMatch="
11622 + (match&IntentFilter.MATCH_CATEGORY_MASK));
11623 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set));
11624 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString());
11627 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
11628 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
11629 && cur.mPref.sameSet(set)) {
11630 // Setting the preferred activity to what it happens to be already
11631 if (DEBUG_PREFERRED) {
11632 Slog.i(TAG, "Replacing with same preferred activity "
11633 + cur.mPref.mShortComponent + " for user "
11635 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11641 if (existing != null) {
11642 if (DEBUG_PREFERRED) {
11643 Slog.i(TAG, existing.size() + " existing preferred matches for:");
11644 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11646 for (int i = 0; i < existing.size(); i++) {
11647 PreferredActivity pa = existing.get(i);
11648 if (DEBUG_PREFERRED) {
11649 Slog.i(TAG, "Removing existing preferred activity "
11650 + pa.mPref.mComponent + ":");
11651 pa.dump(new LogPrinter(Log.INFO, TAG), " ");
11653 pir.removeFilter(pa);
11657 addPreferredActivityInternal(filter, match, set, activity, true, userId,
11658 "Replacing preferred");
11663 public void clearPackagePreferredActivities(String packageName) {
11664 final int uid = Binder.getCallingUid();
11666 synchronized (mPackages) {
11667 PackageParser.Package pkg = mPackages.get(packageName);
11668 if (pkg == null || pkg.applicationInfo.uid != uid) {
11669 if (mContext.checkCallingOrSelfPermission(
11670 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11671 != PackageManager.PERMISSION_GRANTED) {
11672 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
11673 < Build.VERSION_CODES.FROYO) {
11674 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
11675 + Binder.getCallingUid());
11678 mContext.enforceCallingOrSelfPermission(
11679 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11683 int user = UserHandle.getCallingUserId();
11684 if (clearPackagePreferredActivitiesLPw(packageName, user)) {
11685 scheduleWritePackageRestrictionsLocked(user);
11690 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
11691 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
11692 ArrayList<PreferredActivity> removed = null;
11693 boolean changed = false;
11694 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
11695 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
11696 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
11697 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
11700 Iterator<PreferredActivity> it = pir.filterIterator();
11701 while (it.hasNext()) {
11702 PreferredActivity pa = it.next();
11703 // Mark entry for removal only if it matches the package name
11704 // and the entry is of type "always".
11705 if (packageName == null ||
11706 (pa.mPref.mComponent.getPackageName().equals(packageName)
11707 && pa.mPref.mAlways)) {
11708 if (removed == null) {
11709 removed = new ArrayList<PreferredActivity>();
11714 if (removed != null) {
11715 for (int j=0; j<removed.size(); j++) {
11716 PreferredActivity pa = removed.get(j);
11717 pir.removeFilter(pa);
11726 public void resetPreferredActivities(int userId) {
11727 /* TODO: Actually use userId. Why is it being passed in? */
11728 mContext.enforceCallingOrSelfPermission(
11729 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11731 synchronized (mPackages) {
11732 int user = UserHandle.getCallingUserId();
11733 clearPackagePreferredActivitiesLPw(null, user);
11734 mSettings.readDefaultPreferredAppsLPw(this, user);
11735 scheduleWritePackageRestrictionsLocked(user);
11740 public int getPreferredActivities(List<IntentFilter> outFilters,
11741 List<ComponentName> outActivities, String packageName) {
11744 final int userId = UserHandle.getCallingUserId();
11746 synchronized (mPackages) {
11747 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11749 final Iterator<PreferredActivity> it = pir.filterIterator();
11750 while (it.hasNext()) {
11751 final PreferredActivity pa = it.next();
11752 if (packageName == null
11753 || (pa.mPref.mComponent.getPackageName().equals(packageName)
11754 && pa.mPref.mAlways)) {
11755 if (outFilters != null) {
11756 outFilters.add(new IntentFilter(pa));
11758 if (outActivities != null) {
11759 outActivities.add(pa.mPref.mComponent);
11770 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
11772 int callingUid = Binder.getCallingUid();
11773 if (callingUid != Process.SYSTEM_UID) {
11774 throw new SecurityException(
11775 "addPersistentPreferredActivity can only be run by the system");
11777 if (filter.countActions() == 0) {
11778 Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11781 synchronized (mPackages) {
11782 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
11784 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
11785 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
11786 new PersistentPreferredActivity(filter, activity));
11787 scheduleWritePackageRestrictionsLocked(userId);
11792 public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
11793 int callingUid = Binder.getCallingUid();
11794 if (callingUid != Process.SYSTEM_UID) {
11795 throw new SecurityException(
11796 "clearPackagePersistentPreferredActivities can only be run by the system");
11798 ArrayList<PersistentPreferredActivity> removed = null;
11799 boolean changed = false;
11800 synchronized (mPackages) {
11801 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
11802 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
11803 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
11805 if (userId != thisUserId) {
11808 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
11809 while (it.hasNext()) {
11810 PersistentPreferredActivity ppa = it.next();
11811 // Mark entry for removal only if it matches the package name.
11812 if (ppa.mComponent.getPackageName().equals(packageName)) {
11813 if (removed == null) {
11814 removed = new ArrayList<PersistentPreferredActivity>();
11819 if (removed != null) {
11820 for (int j=0; j<removed.size(); j++) {
11821 PersistentPreferredActivity ppa = removed.get(j);
11822 ppir.removeFilter(ppa);
11829 scheduleWritePackageRestrictionsLocked(userId);
11835 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
11836 int ownerUserId, int sourceUserId, int targetUserId, int flags) {
11837 mContext.enforceCallingOrSelfPermission(
11838 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11839 int callingUid = Binder.getCallingUid();
11840 enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11841 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11842 if (intentFilter.countActions() == 0) {
11843 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
11846 synchronized (mPackages) {
11847 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
11848 ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
11849 CrossProfileIntentResolver resolver =
11850 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
11851 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
11852 // We have all those whose filter is equal. Now checking if the rest is equal as well.
11853 if (existing != null) {
11854 int size = existing.size();
11855 for (int i = 0; i < size; i++) {
11856 if (newFilter.equalsIgnoreFilter(existing.get(i))) {
11861 resolver.addFilter(newFilter);
11862 scheduleWritePackageRestrictionsLocked(sourceUserId);
11867 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
11869 mContext.enforceCallingOrSelfPermission(
11870 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11871 int callingUid = Binder.getCallingUid();
11872 enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11873 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11874 int callingUserId = UserHandle.getUserId(callingUid);
11875 synchronized (mPackages) {
11876 CrossProfileIntentResolver resolver =
11877 mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
11878 ArraySet<CrossProfileIntentFilter> set =
11879 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
11880 for (CrossProfileIntentFilter filter : set) {
11881 if (filter.getOwnerPackage().equals(ownerPackage)
11882 && filter.getOwnerUserId() == callingUserId) {
11883 resolver.removeFilter(filter);
11886 scheduleWritePackageRestrictionsLocked(sourceUserId);
11890 // Enforcing that callingUid is owning pkg on userId
11891 private void enforceOwnerRights(String pkg, int userId, int callingUid) {
11892 // The system owns everything.
11893 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
11896 int callingUserId = UserHandle.getUserId(callingUid);
11897 if (callingUserId != userId) {
11898 throw new SecurityException("calling uid " + callingUid
11899 + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
11902 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
11904 throw new IllegalArgumentException("Unknown package " + pkg + " on user "
11907 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
11908 throw new SecurityException("Calling uid " + callingUid
11909 + " does not own package " + pkg);
11914 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
11915 Intent intent = new Intent(Intent.ACTION_MAIN);
11916 intent.addCategory(Intent.CATEGORY_HOME);
11918 final int callingUserId = UserHandle.getCallingUserId();
11919 List<ResolveInfo> list = queryIntentActivities(intent, null,
11920 PackageManager.GET_META_DATA, callingUserId);
11921 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
11922 true, false, false, callingUserId);
11924 allHomeCandidates.clear();
11925 if (list != null) {
11926 for (ResolveInfo ri : list) {
11927 allHomeCandidates.add(ri);
11930 return (preferred == null || preferred.activityInfo == null)
11932 : new ComponentName(preferred.activityInfo.packageName,
11933 preferred.activityInfo.name);
11937 public void setApplicationEnabledSetting(String appPackageName,
11938 int newState, int flags, int userId, String callingPackage) {
11939 if (!sUserManager.exists(userId)) return;
11940 if (callingPackage == null) {
11941 callingPackage = Integer.toString(Binder.getCallingUid());
11943 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
11947 public void setComponentEnabledSetting(ComponentName componentName,
11948 int newState, int flags, int userId) {
11949 if (!sUserManager.exists(userId)) return;
11950 setEnabledSetting(componentName.getPackageName(),
11951 componentName.getClassName(), newState, flags, userId, null);
11954 private void setEnabledSetting(final String packageName, String className, int newState,
11955 final int flags, int userId, String callingPackage) {
11956 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
11957 || newState == COMPONENT_ENABLED_STATE_ENABLED
11958 || newState == COMPONENT_ENABLED_STATE_DISABLED
11959 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
11960 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
11961 throw new IllegalArgumentException("Invalid new component state: "
11964 PackageSetting pkgSetting;
11965 final int uid = Binder.getCallingUid();
11966 final int permission = mContext.checkCallingOrSelfPermission(
11967 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
11968 enforceCrossUserPermission(uid, userId, false, true, "set enabled");
11969 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
11970 boolean sendNow = false;
11971 boolean isApp = (className == null);
11972 String componentName = isApp ? packageName : className;
11973 int packageUid = -1;
11974 ArrayList<String> components;
11977 synchronized (mPackages) {
11978 pkgSetting = mSettings.mPackages.get(packageName);
11979 if (pkgSetting == null) {
11980 if (className == null) {
11981 throw new IllegalArgumentException(
11982 "Unknown package: " + packageName);
11984 throw new IllegalArgumentException(
11985 "Unknown component: " + packageName
11986 + "/" + className);
11988 // Allow root and verify that userId is not being specified by a different user
11989 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
11990 throw new SecurityException(
11991 "Permission Denial: attempt to change component state from pid="
11992 + Binder.getCallingPid()
11993 + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
11995 if (className == null) {
11996 // We're dealing with an application/package level state change
11997 if (pkgSetting.getEnabled(userId) == newState) {
12001 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
12002 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
12003 // Don't care about who enables an app.
12004 callingPackage = null;
12006 pkgSetting.setEnabled(newState, userId, callingPackage);
12007 // pkgSetting.pkg.mSetEnabled = newState;
12009 // We're dealing with a component level state change
12010 // First, verify that this is a valid class name.
12011 PackageParser.Package pkg = pkgSetting.pkg;
12012 if (pkg == null || !pkg.hasComponentClassName(className)) {
12013 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
12014 throw new IllegalArgumentException("Component class " + className
12015 + " does not exist in " + packageName);
12017 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
12018 + className + " does not exist in " + packageName);
12021 switch (newState) {
12022 case COMPONENT_ENABLED_STATE_ENABLED:
12023 if (!pkgSetting.enableComponentLPw(className, userId)) {
12027 case COMPONENT_ENABLED_STATE_DISABLED:
12028 if (!pkgSetting.disableComponentLPw(className, userId)) {
12032 case COMPONENT_ENABLED_STATE_DEFAULT:
12033 if (!pkgSetting.restoreComponentLPw(className, userId)) {
12038 Slog.e(TAG, "Invalid new component state: " + newState);
12042 mSettings.writePackageRestrictionsLPr(userId);
12043 components = mPendingBroadcasts.get(userId, packageName);
12044 final boolean newPackage = components == null;
12046 components = new ArrayList<String>();
12048 if (!components.contains(componentName)) {
12049 components.add(componentName);
12051 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
12053 // Purge entry from pending broadcast list if another one exists already
12054 // since we are sending one right away.
12055 mPendingBroadcasts.remove(userId, packageName);
12058 mPendingBroadcasts.put(userId, packageName, components);
12060 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
12061 // Schedule a message
12062 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
12067 long callingId = Binder.clearCallingIdentity();
12070 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
12071 sendPackageChangedBroadcast(packageName,
12072 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
12075 Binder.restoreCallingIdentity(callingId);
12079 private void sendPackageChangedBroadcast(String packageName,
12080 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
12082 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
12084 Bundle extras = new Bundle(4);
12085 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
12086 String nameList[] = new String[componentNames.size()];
12087 componentNames.toArray(nameList);
12088 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
12089 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
12090 extras.putInt(Intent.EXTRA_UID, packageUid);
12091 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
12092 new int[] {UserHandle.getUserId(packageUid)});
12096 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
12097 if (!sUserManager.exists(userId)) return;
12098 final int uid = Binder.getCallingUid();
12099 final int permission = mContext.checkCallingOrSelfPermission(
12100 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
12101 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
12102 enforceCrossUserPermission(uid, userId, true, true, "stop package");
12104 synchronized (mPackages) {
12105 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
12107 scheduleWritePackageRestrictionsLocked(userId);
12113 public String getInstallerPackageName(String packageName) {
12115 synchronized (mPackages) {
12116 return mSettings.getInstallerPackageNameLPr(packageName);
12121 public int getApplicationEnabledSetting(String packageName, int userId) {
12122 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12123 int uid = Binder.getCallingUid();
12124 enforceCrossUserPermission(uid, userId, false, false, "get enabled");
12126 synchronized (mPackages) {
12127 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
12132 public int getComponentEnabledSetting(ComponentName componentName, int userId) {
12133 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12134 int uid = Binder.getCallingUid();
12135 enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
12137 synchronized (mPackages) {
12138 return mSettings.getComponentEnabledSettingLPr(componentName, userId);
12143 public void enterSafeMode() {
12144 enforceSystemOrRoot("Only the system can request entering safe mode");
12146 if (!mSystemReady) {
12152 public void systemReady() {
12153 mSystemReady = true;
12155 // Read the compatibilty setting when the system is ready.
12156 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
12157 mContext.getContentResolver(),
12158 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
12159 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
12160 if (DEBUG_SETTINGS) {
12161 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
12164 synchronized (mPackages) {
12165 // Verify that all of the preferred activity components actually
12166 // exist. It is possible for applications to be updated and at
12167 // that point remove a previously declared activity component that
12168 // had been set as a preferred activity. We try to clean this up
12169 // the next time we encounter that preferred activity, but it is
12170 // possible for the user flow to never be able to return to that
12171 // situation so here we do a sanity check to make sure we haven't
12172 // left any junk around.
12173 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
12174 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12175 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12177 for (PreferredActivity pa : pir.filterSet()) {
12178 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
12182 if (removed.size() > 0) {
12183 for (int r=0; r<removed.size(); r++) {
12184 PreferredActivity pa = removed.get(r);
12185 Slog.w(TAG, "Removing dangling preferred activity: "
12186 + pa.mPref.mComponent);
12187 pir.removeFilter(pa);
12189 mSettings.writePackageRestrictionsLPr(
12190 mSettings.mPreferredActivities.keyAt(i));
12194 sUserManager.systemReady();
12196 // Kick off any messages waiting for system ready
12197 if (mPostSystemReadyMessages != null) {
12198 for (Message msg : mPostSystemReadyMessages) {
12199 msg.sendToTarget();
12201 mPostSystemReadyMessages = null;
12206 public boolean isSafeMode() {
12211 public boolean hasSystemUidErrors() {
12212 return mHasSystemUidErrors;
12215 static String arrayToString(int[] array) {
12216 StringBuffer buf = new StringBuffer(128);
12218 if (array != null) {
12219 for (int i=0; i<array.length; i++) {
12220 if (i > 0) buf.append(", ");
12221 buf.append(array[i]);
12225 return buf.toString();
12228 static class DumpState {
12229 public static final int DUMP_LIBS = 1 << 0;
12230 public static final int DUMP_FEATURES = 1 << 1;
12231 public static final int DUMP_RESOLVERS = 1 << 2;
12232 public static final int DUMP_PERMISSIONS = 1 << 3;
12233 public static final int DUMP_PACKAGES = 1 << 4;
12234 public static final int DUMP_SHARED_USERS = 1 << 5;
12235 public static final int DUMP_MESSAGES = 1 << 6;
12236 public static final int DUMP_PROVIDERS = 1 << 7;
12237 public static final int DUMP_VERIFIERS = 1 << 8;
12238 public static final int DUMP_PREFERRED = 1 << 9;
12239 public static final int DUMP_PREFERRED_XML = 1 << 10;
12240 public static final int DUMP_KEYSETS = 1 << 11;
12241 public static final int DUMP_VERSION = 1 << 12;
12242 public static final int DUMP_INSTALLS = 1 << 13;
12244 public static final int OPTION_SHOW_FILTERS = 1 << 0;
12246 private int mTypes;
12248 private int mOptions;
12250 private boolean mTitlePrinted;
12252 private SharedUserSetting mSharedUser;
12254 public boolean isDumping(int type) {
12255 if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
12259 return (mTypes & type) != 0;
12262 public void setDump(int type) {
12266 public boolean isOptionEnabled(int option) {
12267 return (mOptions & option) != 0;
12270 public void setOptionEnabled(int option) {
12271 mOptions |= option;
12274 public boolean onTitlePrinted() {
12275 final boolean printed = mTitlePrinted;
12276 mTitlePrinted = true;
12280 public boolean getTitlePrinted() {
12281 return mTitlePrinted;
12284 public void setTitlePrinted(boolean enabled) {
12285 mTitlePrinted = enabled;
12288 public SharedUserSetting getSharedUser() {
12289 return mSharedUser;
12292 public void setSharedUser(SharedUserSetting user) {
12293 mSharedUser = user;
12298 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12299 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
12300 != PackageManager.PERMISSION_GRANTED) {
12301 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12302 + Binder.getCallingPid()
12303 + ", uid=" + Binder.getCallingUid()
12304 + " without permission "
12305 + android.Manifest.permission.DUMP);
12309 DumpState dumpState = new DumpState();
12310 boolean fullPreferred = false;
12311 boolean checkin = false;
12313 String packageName = null;
12316 while (opti < args.length) {
12317 String opt = args[opti];
12318 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12323 if ("-a".equals(opt)) {
12324 // Right now we only know how to print all.
12325 } else if ("-h".equals(opt)) {
12326 pw.println("Package manager dump options:");
12327 pw.println(" [-h] [-f] [--checkin] [cmd] ...");
12328 pw.println(" --checkin: dump for a checkin");
12329 pw.println(" -f: print details of intent filters");
12330 pw.println(" -h: print this help");
12331 pw.println(" cmd may be one of:");
12332 pw.println(" l[ibraries]: list known shared libraries");
12333 pw.println(" f[ibraries]: list device features");
12334 pw.println(" k[eysets]: print known keysets");
12335 pw.println(" r[esolvers]: dump intent resolvers");
12336 pw.println(" perm[issions]: dump permissions");
12337 pw.println(" pref[erred]: print preferred package settings");
12338 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
12339 pw.println(" prov[iders]: dump content providers");
12340 pw.println(" p[ackages]: dump installed packages");
12341 pw.println(" s[hared-users]: dump shared user IDs");
12342 pw.println(" m[essages]: print collected runtime messages");
12343 pw.println(" v[erifiers]: print package verifier info");
12344 pw.println(" version: print database version info");
12345 pw.println(" write: write current settings now");
12346 pw.println(" <package.name>: info about given package");
12347 pw.println(" installs: details about install sessions");
12349 } else if ("--checkin".equals(opt)) {
12351 } else if ("-f".equals(opt)) {
12352 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12354 pw.println("Unknown argument: " + opt + "; use -h for help");
12358 // Is the caller requesting to dump a particular piece of data?
12359 if (opti < args.length) {
12360 String cmd = args[opti];
12362 // Is this a package name?
12363 if ("android".equals(cmd) || cmd.contains(".")) {
12365 // When dumping a single package, we always dump all of its
12366 // filter information since the amount of data will be reasonable.
12367 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12368 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
12369 dumpState.setDump(DumpState.DUMP_LIBS);
12370 } else if ("f".equals(cmd) || "features".equals(cmd)) {
12371 dumpState.setDump(DumpState.DUMP_FEATURES);
12372 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
12373 dumpState.setDump(DumpState.DUMP_RESOLVERS);
12374 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
12375 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
12376 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
12377 dumpState.setDump(DumpState.DUMP_PREFERRED);
12378 } else if ("preferred-xml".equals(cmd)) {
12379 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
12380 if (opti < args.length && "--full".equals(args[opti])) {
12381 fullPreferred = true;
12384 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
12385 dumpState.setDump(DumpState.DUMP_PACKAGES);
12386 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
12387 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
12388 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
12389 dumpState.setDump(DumpState.DUMP_PROVIDERS);
12390 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
12391 dumpState.setDump(DumpState.DUMP_MESSAGES);
12392 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
12393 dumpState.setDump(DumpState.DUMP_VERIFIERS);
12394 } else if ("version".equals(cmd)) {
12395 dumpState.setDump(DumpState.DUMP_VERSION);
12396 } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
12397 dumpState.setDump(DumpState.DUMP_KEYSETS);
12398 } else if ("installs".equals(cmd)) {
12399 dumpState.setDump(DumpState.DUMP_INSTALLS);
12400 } else if ("write".equals(cmd)) {
12401 synchronized (mPackages) {
12402 mSettings.writeLPr();
12403 pw.println("Settings written.");
12410 pw.println("vers,1");
12414 synchronized (mPackages) {
12415 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
12417 if (dumpState.onTitlePrinted())
12419 pw.println("Database versions:");
12420 pw.print(" SDK Version:");
12421 pw.print(" internal=");
12422 pw.print(mSettings.mInternalSdkPlatform);
12423 pw.print(" external=");
12424 pw.println(mSettings.mExternalSdkPlatform);
12425 pw.print(" DB Version:");
12426 pw.print(" internal=");
12427 pw.print(mSettings.mInternalDatabaseVersion);
12428 pw.print(" external=");
12429 pw.println(mSettings.mExternalDatabaseVersion);
12433 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
12435 if (dumpState.onTitlePrinted())
12437 pw.println("Verifiers:");
12438 pw.print(" Required: ");
12439 pw.print(mRequiredVerifierPackage);
12440 pw.print(" (uid=");
12441 pw.print(getPackageUid(mRequiredVerifierPackage, 0));
12443 } else if (mRequiredVerifierPackage != null) {
12444 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
12445 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
12449 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
12450 boolean printedHeader = false;
12451 final Iterator<String> it = mSharedLibraries.keySet().iterator();
12452 while (it.hasNext()) {
12453 String name = it.next();
12454 SharedLibraryEntry ent = mSharedLibraries.get(name);
12456 if (!printedHeader) {
12457 if (dumpState.onTitlePrinted())
12459 pw.println("Libraries:");
12460 printedHeader = true;
12470 if (ent.path != null) {
12472 pw.print("(jar) ");
12473 pw.print(ent.path);
12476 pw.print(ent.path);
12480 pw.print("(apk) ");
12491 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
12492 if (dumpState.onTitlePrinted())
12495 pw.println("Features:");
12497 Iterator<String> it = mAvailableFeatures.keySet().iterator();
12498 while (it.hasNext()) {
12499 String name = it.next();
12509 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
12510 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
12511 : "Activity Resolver Table:", " ", packageName,
12512 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12513 dumpState.setTitlePrinted(true);
12515 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
12516 : "Receiver Resolver Table:", " ", packageName,
12517 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12518 dumpState.setTitlePrinted(true);
12520 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
12521 : "Service Resolver Table:", " ", packageName,
12522 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12523 dumpState.setTitlePrinted(true);
12525 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
12526 : "Provider Resolver Table:", " ", packageName,
12527 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12528 dumpState.setTitlePrinted(true);
12532 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
12533 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12534 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12535 int user = mSettings.mPreferredActivities.keyAt(i);
12537 dumpState.getTitlePrinted()
12538 ? "\nPreferred Activities User " + user + ":"
12539 : "Preferred Activities User " + user + ":", " ",
12540 packageName, true)) {
12541 dumpState.setTitlePrinted(true);
12546 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
12548 FileOutputStream fout = new FileOutputStream(fd);
12549 BufferedOutputStream str = new BufferedOutputStream(fout);
12550 XmlSerializer serializer = new FastXmlSerializer();
12552 serializer.setOutput(str, "utf-8");
12553 serializer.startDocument(null, true);
12554 serializer.setFeature(
12555 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
12556 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
12557 serializer.endDocument();
12558 serializer.flush();
12559 } catch (IllegalArgumentException e) {
12560 pw.println("Failed writing: " + e);
12561 } catch (IllegalStateException e) {
12562 pw.println("Failed writing: " + e);
12563 } catch (IOException e) {
12564 pw.println("Failed writing: " + e);
12568 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
12569 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
12570 if (packageName == null) {
12571 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
12573 if (dumpState.onTitlePrinted())
12575 pw.println("AppOp Permissions:");
12577 pw.print(" AppOp Permission ");
12578 pw.print(mAppOpPermissionPackages.keyAt(iperm));
12580 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
12581 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
12582 pw.print(" "); pw.println(pkgs.valueAt(ipkg));
12588 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
12589 boolean printedSomething = false;
12590 for (PackageParser.Provider p : mProviders.mProviders.values()) {
12591 if (packageName != null && !packageName.equals(p.info.packageName)) {
12594 if (!printedSomething) {
12595 if (dumpState.onTitlePrinted())
12597 pw.println("Registered ContentProviders:");
12598 printedSomething = true;
12600 pw.print(" "); p.printComponentShortName(pw); pw.println(":");
12601 pw.print(" "); pw.println(p.toString());
12603 printedSomething = false;
12604 for (Map.Entry<String, PackageParser.Provider> entry :
12605 mProvidersByAuthority.entrySet()) {
12606 PackageParser.Provider p = entry.getValue();
12607 if (packageName != null && !packageName.equals(p.info.packageName)) {
12610 if (!printedSomething) {
12611 if (dumpState.onTitlePrinted())
12613 pw.println("ContentProvider Authorities:");
12614 printedSomething = true;
12616 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
12617 pw.print(" "); pw.println(p.toString());
12618 if (p.info != null && p.info.applicationInfo != null) {
12619 final String appInfo = p.info.applicationInfo.toString();
12620 pw.print(" applicationInfo="); pw.println(appInfo);
12625 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
12626 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
12629 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
12630 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
12633 if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
12634 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
12637 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
12638 // XXX should handle packageName != null by dumping only install data that
12639 // the given package is involved with.
12640 if (dumpState.onTitlePrinted()) pw.println();
12641 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120));
12644 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
12645 if (dumpState.onTitlePrinted()) pw.println();
12646 mSettings.dumpReadMessagesLPr(pw, dumpState);
12649 pw.println("Package warning messages:");
12650 final File fname = getSettingsProblemFile();
12651 FileInputStream in = null;
12653 in = new FileInputStream(fname);
12654 final int avail = in.available();
12655 final byte[] data = new byte[avail];
12657 pw.print(new String(data));
12658 } catch (FileNotFoundException e) {
12659 } catch (IOException e) {
12664 } catch (IOException e) {
12670 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
12671 BufferedReader in = null;
12672 String line = null;
12674 in = new BufferedReader(new FileReader(getSettingsProblemFile()));
12675 while ((line = in.readLine()) != null) {
12679 } catch (IOException ignored) {
12681 IoUtils.closeQuietly(in);
12687 // ------- apps on sdcard specific code -------
12688 static final boolean DEBUG_SD_INSTALL = false;
12690 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
12692 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
12694 private boolean mMediaMounted = false;
12696 static String getEncryptKey() {
12698 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
12699 SD_ENCRYPTION_KEYSTORE_NAME);
12700 if (sdEncKey == null) {
12701 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
12702 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
12703 if (sdEncKey == null) {
12704 Slog.e(TAG, "Failed to create encryption keys");
12709 } catch (NoSuchAlgorithmException nsae) {
12710 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
12712 } catch (IOException ioe) {
12713 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
12719 * Update media status on PackageManager.
12722 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
12723 int callingUid = Binder.getCallingUid();
12724 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12725 throw new SecurityException("Media status can only be updated by the system");
12727 // reader; this apparently protects mMediaMounted, but should probably
12728 // be a different lock in that case.
12729 synchronized (mPackages) {
12730 Log.i(TAG, "Updating external media status from "
12731 + (mMediaMounted ? "mounted" : "unmounted") + " to "
12732 + (mediaStatus ? "mounted" : "unmounted"));
12733 if (DEBUG_SD_INSTALL)
12734 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
12735 + ", mMediaMounted=" + mMediaMounted);
12736 if (mediaStatus == mMediaMounted) {
12737 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
12739 mHandler.sendMessage(msg);
12742 mMediaMounted = mediaStatus;
12744 // Queue up an async operation since the package installation may take a
12746 mHandler.post(new Runnable() {
12747 public void run() {
12748 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
12754 * Called by MountService when the initial ASECs to scan are available.
12755 * Should block until all the ASEC containers are finished being scanned.
12757 public void scanAvailableAsecs() {
12758 updateExternalMediaStatusInner(true, false, false);
12759 if (mShouldRestoreconData) {
12760 SELinuxMMAC.setRestoreconDone();
12761 mShouldRestoreconData = false;
12766 * Collect information of applications on external media, map them against
12767 * existing containers and update information based on current mount status.
12768 * Please note that we always have to report status if reportStatus has been
12769 * set to true especially when unloading packages.
12771 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
12772 boolean externalStorage) {
12773 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
12774 int[] uidArr = EmptyArray.INT;
12776 final String[] list = PackageHelper.getSecureContainerList();
12777 if (ArrayUtils.isEmpty(list)) {
12778 Log.i(TAG, "No secure containers found");
12780 // Process list of secure containers and categorize them
12781 // as active or stale based on their package internal state.
12784 synchronized (mPackages) {
12785 for (String cid : list) {
12786 // Leave stages untouched for now; installer service owns them
12787 if (PackageInstallerService.isStageName(cid)) continue;
12789 if (DEBUG_SD_INSTALL)
12790 Log.i(TAG, "Processing container " + cid);
12791 String pkgName = getAsecPackageName(cid);
12792 if (pkgName == null) {
12793 Slog.i(TAG, "Found stale container " + cid + " with no package name");
12796 if (DEBUG_SD_INSTALL)
12797 Log.i(TAG, "Looking for pkg : " + pkgName);
12799 final PackageSetting ps = mSettings.mPackages.get(pkgName);
12801 Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
12806 * Skip packages that are not external if we're unmounting
12807 * external storage.
12809 if (externalStorage && !isMounted && !isExternal(ps)) {
12813 final AsecInstallArgs args = new AsecInstallArgs(cid,
12814 getAppDexInstructionSets(ps), isForwardLocked(ps));
12815 // The package status is changed only if the code path
12816 // matches between settings and the container id.
12817 if (ps.codePathString != null
12818 && ps.codePathString.startsWith(args.getCodePath())) {
12819 if (DEBUG_SD_INSTALL) {
12820 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
12821 + " at code path: " + ps.codePathString);
12824 // We do have a valid package installed on sdcard
12825 processCids.put(args, ps.codePathString);
12826 final int uid = ps.appId;
12828 uidArr = ArrayUtils.appendInt(uidArr, uid);
12831 Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
12832 + ps.codePathString);
12837 Arrays.sort(uidArr);
12840 // Process packages with valid entries.
12842 if (DEBUG_SD_INSTALL)
12843 Log.i(TAG, "Loading packages");
12844 loadMediaPackages(processCids, uidArr);
12845 startCleaningPackages();
12846 mInstallerService.onSecureContainersAvailable();
12848 if (DEBUG_SD_INSTALL)
12849 Log.i(TAG, "Unloading packages");
12850 unloadMediaPackages(processCids, uidArr, reportStatus);
12854 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
12855 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
12856 int size = pkgList.size();
12858 // Send broadcasts here
12859 Bundle extras = new Bundle();
12860 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
12861 .toArray(new String[size]));
12862 if (uidArr != null) {
12863 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
12866 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
12868 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
12869 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
12870 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
12875 * Look at potentially valid container ids from processCids If package
12876 * information doesn't match the one on record or package scanning fails,
12877 * the cid is added to list of removeCids. We currently don't delete stale
12880 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
12881 ArrayList<String> pkgList = new ArrayList<String>();
12882 Set<AsecInstallArgs> keys = processCids.keySet();
12884 for (AsecInstallArgs args : keys) {
12885 String codePath = processCids.get(args);
12886 if (DEBUG_SD_INSTALL)
12887 Log.i(TAG, "Loading container : " + args.cid);
12888 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12890 // Make sure there are no container errors first.
12891 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
12892 Slog.e(TAG, "Failed to mount cid : " + args.cid
12893 + " when installing from sdcard");
12896 // Check code path here.
12897 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
12898 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
12899 + " does not match one in settings " + codePath);
12903 int parseFlags = mDefParseFlags;
12904 if (args.isExternal()) {
12905 parseFlags |= PackageParser.PARSE_ON_SDCARD;
12907 if (args.isFwdLocked()) {
12908 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
12911 synchronized (mInstallLock) {
12912 PackageParser.Package pkg = null;
12914 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
12915 } catch (PackageManagerException e) {
12916 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
12918 // Scan the package
12921 * TODO why is the lock being held? doPostInstall is
12922 * called in other places without the lock. This needs
12923 * to be straightened out.
12926 synchronized (mPackages) {
12927 retCode = PackageManager.INSTALL_SUCCEEDED;
12928 pkgList.add(pkg.packageName);
12929 // Post process args
12930 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
12931 pkg.applicationInfo.uid);
12934 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard");
12939 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
12940 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
12945 synchronized (mPackages) {
12946 // If the platform SDK has changed since the last time we booted,
12947 // we need to re-grant app permission to catch any new ones that
12948 // appear. This is really a hack, and means that apps can in some
12949 // cases get permissions that the user didn't initially explicitly
12950 // allow... it would be nice to have some better way to handle
12952 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
12953 if (regrantPermissions)
12954 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
12955 + mSdkVersion + "; regranting permissions for external storage");
12956 mSettings.mExternalSdkPlatform = mSdkVersion;
12958 // Make sure group IDs have been assigned, and any permission
12959 // changes in other apps are accounted for
12960 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
12961 | (regrantPermissions
12962 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
12965 mSettings.updateExternalDatabaseVersion();
12967 // can downgrade to reader
12968 // Persist settings
12969 mSettings.writeLPr();
12971 // Send a broadcast to let everyone know we are done processing
12972 if (pkgList.size() > 0) {
12973 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
12978 * Utility method to unload a list of specified containers
12980 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
12981 // Just unmount all valid containers.
12982 for (AsecInstallArgs arg : cidArgs) {
12983 synchronized (mInstallLock) {
12984 arg.doPostDeleteLI(false);
12990 * Unload packages mounted on external media. This involves deleting package
12991 * data from internal structures, sending broadcasts about diabled packages,
12992 * gc'ing to free up references, unmounting all secure containers
12993 * corresponding to packages on external media, and posting a
12994 * UPDATED_MEDIA_STATUS message if status has been requested. Please note
12995 * that we always have to post this message if status has been requested no
12998 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
12999 final boolean reportStatus) {
13000 if (DEBUG_SD_INSTALL)
13001 Log.i(TAG, "unloading media packages");
13002 ArrayList<String> pkgList = new ArrayList<String>();
13003 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
13004 final Set<AsecInstallArgs> keys = processCids.keySet();
13005 for (AsecInstallArgs args : keys) {
13006 String pkgName = args.getPackageName();
13007 if (DEBUG_SD_INSTALL)
13008 Log.i(TAG, "Trying to unload pkg : " + pkgName);
13009 // Delete package internally
13010 PackageRemovedInfo outInfo = new PackageRemovedInfo();
13011 synchronized (mInstallLock) {
13012 boolean res = deletePackageLI(pkgName, null, false, null, null,
13013 PackageManager.DELETE_KEEP_DATA, outInfo, false);
13015 pkgList.add(pkgName);
13017 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
13018 failedList.add(args);
13024 synchronized (mPackages) {
13025 // We didn't update the settings after removing each package;
13026 // write them now for all packages.
13027 mSettings.writeLPr();
13030 // We have to absolutely send UPDATED_MEDIA_STATUS only
13031 // after confirming that all the receivers processed the ordered
13032 // broadcast when packages get disabled, force a gc to clean things up.
13033 // and unload all the containers.
13034 if (pkgList.size() > 0) {
13035 sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
13036 new IIntentReceiver.Stub() {
13037 public void performReceive(Intent intent, int resultCode, String data,
13038 Bundle extras, boolean ordered, boolean sticky,
13039 int sendingUser) throws RemoteException {
13040 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
13041 reportStatus ? 1 : 0, 1, keys);
13042 mHandler.sendMessage(msg);
13046 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
13048 mHandler.sendMessage(msg);
13054 public void movePackage(final String packageName, final IPackageMoveObserver observer,
13056 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
13057 UserHandle user = new UserHandle(UserHandle.getCallingUserId());
13058 int returnCode = PackageManager.MOVE_SUCCEEDED;
13059 int currInstallFlags = 0;
13060 int newInstallFlags = 0;
13062 File codeFile = null;
13063 String installerPackageName = null;
13064 String packageAbiOverride = null;
13067 synchronized (mPackages) {
13068 final PackageParser.Package pkg = mPackages.get(packageName);
13069 final PackageSetting ps = mSettings.mPackages.get(packageName);
13070 if (pkg == null || ps == null) {
13071 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
13073 // Disable moving fwd locked apps and system packages
13074 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
13075 Slog.w(TAG, "Cannot move system application");
13076 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
13077 } else if (pkg.mOperationPending) {
13078 Slog.w(TAG, "Attempt to move package which has pending operations");
13079 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
13081 // Find install location first
13082 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13083 && (flags & PackageManager.MOVE_INTERNAL) != 0) {
13084 Slog.w(TAG, "Ambigous flags specified for move location.");
13085 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13087 newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13088 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13089 currInstallFlags = isExternal(pkg)
13090 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13092 if (newInstallFlags == currInstallFlags) {
13093 Slog.w(TAG, "No move required. Trying to move to same location");
13094 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13096 if (isForwardLocked(pkg)) {
13097 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13098 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13102 if (returnCode == PackageManager.MOVE_SUCCEEDED) {
13103 pkg.mOperationPending = true;
13107 codeFile = new File(pkg.codePath);
13108 installerPackageName = ps.installerPackageName;
13109 packageAbiOverride = ps.cpuAbiOverrideString;
13113 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
13115 observer.packageMoved(packageName, returnCode);
13116 } catch (RemoteException ignored) {
13121 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
13123 public void onUserActionRequired(Intent intent) throws RemoteException {
13124 throw new IllegalStateException();
13128 public void onPackageInstalled(String basePackageName, int returnCode, String msg,
13129 Bundle extras) throws RemoteException {
13130 Slog.d(TAG, "Install result for move: "
13131 + PackageManager.installStatusToString(returnCode, msg));
13133 // We usually have a new package now after the install, but if
13134 // we failed we need to clear the pending flag on the original
13136 synchronized (mPackages) {
13137 final PackageParser.Package pkg = mPackages.get(packageName);
13139 pkg.mOperationPending = false;
13143 final int status = PackageManager.installStatusToPublicStatus(returnCode);
13145 case PackageInstaller.STATUS_SUCCESS:
13146 observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
13148 case PackageInstaller.STATUS_FAILURE_STORAGE:
13149 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
13152 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
13158 // Treat a move like reinstalling an existing app, which ensures that we
13159 // process everythign uniformly, like unpacking native libraries.
13160 newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
13162 final Message msg = mHandler.obtainMessage(INIT_COPY);
13163 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
13164 msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
13165 installerPackageName, null, user, packageAbiOverride);
13166 mHandler.sendMessage(msg);
13170 public boolean setInstallLocation(int loc) {
13171 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
13173 if (getInstallLocation() == loc) {
13176 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
13177 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
13178 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
13179 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
13186 public int getInstallLocation() {
13187 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13188 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
13189 PackageHelper.APP_INSTALL_AUTO);
13192 /** Called by UserManagerService */
13193 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
13194 mDirtyUsers.remove(userHandle);
13195 mSettings.removeUserLPw(userHandle);
13196 mPendingBroadcasts.remove(userHandle);
13197 if (mInstaller != null) {
13198 // Technically, we shouldn't be doing this with the package lock
13199 // held. However, this is very rare, and there is already so much
13200 // other disk I/O going on, that we'll let it slide for now.
13201 mInstaller.removeUserDataDirs(userHandle);
13203 mUserNeedsBadging.delete(userHandle);
13204 removeUnusedPackagesLILPw(userManager, userHandle);
13208 * We're removing userHandle and would like to remove any downloaded packages
13209 * that are no longer in use by any other user.
13210 * @param userHandle the user being removed
13212 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
13213 final boolean DEBUG_CLEAN_APKS = false;
13214 int [] users = userManager.getUserIdsLPr();
13215 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
13216 while (psit.hasNext()) {
13217 PackageSetting ps = psit.next();
13218 if (ps.pkg == null) {
13221 final String packageName = ps.pkg.packageName;
13222 // Skip over if system app
13223 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13226 if (DEBUG_CLEAN_APKS) {
13227 Slog.i(TAG, "Checking package " + packageName);
13229 boolean keep = false;
13230 for (int i = 0; i < users.length; i++) {
13231 if (users[i] != userHandle && ps.getInstalled(users[i])) {
13233 if (DEBUG_CLEAN_APKS) {
13234 Slog.i(TAG, " Keeping package " + packageName + " for user "
13241 if (DEBUG_CLEAN_APKS) {
13242 Slog.i(TAG, " Removing package " + packageName);
13244 mHandler.post(new Runnable() {
13245 public void run() {
13246 deletePackageX(packageName, userHandle, 0);
13253 /** Called by UserManagerService */
13254 void createNewUserLILPw(int userHandle, File path) {
13255 if (mInstaller != null) {
13256 mInstaller.createUserConfig(userHandle);
13257 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
13262 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
13263 mContext.enforceCallingOrSelfPermission(
13264 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13265 "Only package verification agents can read the verifier device identity");
13267 synchronized (mPackages) {
13268 return mSettings.getVerifierDeviceIdentityLPw();
13273 public void setPermissionEnforced(String permission, boolean enforced) {
13274 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
13275 if (READ_EXTERNAL_STORAGE.equals(permission)) {
13276 synchronized (mPackages) {
13277 if (mSettings.mReadExternalStorageEnforced == null
13278 || mSettings.mReadExternalStorageEnforced != enforced) {
13279 mSettings.mReadExternalStorageEnforced = enforced;
13280 mSettings.writeLPr();
13283 // kill any non-foreground processes so we restart them and
13284 // grant/revoke the GID.
13285 final IActivityManager am = ActivityManagerNative.getDefault();
13287 final long token = Binder.clearCallingIdentity();
13289 am.killProcessesBelowForeground("setPermissionEnforcement");
13290 } catch (RemoteException e) {
13292 Binder.restoreCallingIdentity(token);
13296 throw new IllegalArgumentException("No selective enforcement for " + permission);
13302 public boolean isPermissionEnforced(String permission) {
13307 public boolean isStorageLow() {
13308 final long token = Binder.clearCallingIdentity();
13310 final DeviceStorageMonitorInternal
13311 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13313 return dsm.isMemoryLow();
13318 Binder.restoreCallingIdentity(token);
13323 public IPackageInstaller getPackageInstaller() {
13324 return mInstallerService;
13327 private boolean userNeedsBadging(int userId) {
13328 int index = mUserNeedsBadging.indexOfKey(userId);
13330 final UserInfo userInfo;
13331 final long token = Binder.clearCallingIdentity();
13333 userInfo = sUserManager.getUserInfo(userId);
13335 Binder.restoreCallingIdentity(token);
13338 if (userInfo != null && userInfo.isManagedProfile()) {
13343 mUserNeedsBadging.put(userId, b);
13346 return mUserNeedsBadging.valueAt(index);
13350 public KeySet getKeySetByAlias(String packageName, String alias) {
13351 if (packageName == null || alias == null) {
13354 synchronized(mPackages) {
13355 final PackageParser.Package pkg = mPackages.get(packageName);
13357 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13358 throw new IllegalArgumentException("Unknown package: " + packageName);
13360 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13361 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
13366 public KeySet getSigningKeySet(String packageName) {
13367 if (packageName == null) {
13370 synchronized(mPackages) {
13371 final PackageParser.Package pkg = mPackages.get(packageName);
13373 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13374 throw new IllegalArgumentException("Unknown package: " + packageName);
13376 if (pkg.applicationInfo.uid != Binder.getCallingUid()
13377 && Process.SYSTEM_UID != Binder.getCallingUid()) {
13378 throw new SecurityException("May not access signing KeySet of other apps.");
13380 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13381 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
13386 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
13387 if (packageName == null || ks == null) {
13390 synchronized(mPackages) {
13391 final PackageParser.Package pkg = mPackages.get(packageName);
13393 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13394 throw new IllegalArgumentException("Unknown package: " + packageName);
13396 IBinder ksh = ks.getToken();
13397 if (ksh instanceof KeySetHandle) {
13398 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13399 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
13406 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
13407 if (packageName == null || ks == null) {
13410 synchronized(mPackages) {
13411 final PackageParser.Package pkg = mPackages.get(packageName);
13413 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13414 throw new IllegalArgumentException("Unknown package: " + packageName);
13416 IBinder ksh = ks.getToken();
13417 if (ksh instanceof KeySetHandle) {
13418 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13419 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
13425 public void getUsageStatsIfNoPackageUsageInfo() {
13426 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
13427 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
13429 throw new IllegalStateException("UsageStatsManager must be initialized");
13431 long now = System.currentTimeMillis();
13432 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
13433 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
13434 String packageName = entry.getKey();
13435 PackageParser.Package pkg = mPackages.get(packageName);
13439 UsageStats usage = entry.getValue();
13440 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
13441 mPackageUsage.mIsHistoricalPackageUsageAvailable = true;