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 com.android.internal.util.ArrayUtils.appendInt;
27 import static com.android.internal.util.ArrayUtils.removeInt;
28 import static libcore.io.OsConstants.S_IRWXU;
29 import static libcore.io.OsConstants.S_IRGRP;
30 import static libcore.io.OsConstants.S_IXGRP;
31 import static libcore.io.OsConstants.S_IROTH;
32 import static libcore.io.OsConstants.S_IXOTH;
34 import com.android.internal.app.IMediaContainerService;
35 import com.android.internal.app.ResolverActivity;
36 import com.android.internal.content.NativeLibraryHelper;
37 import com.android.internal.content.PackageHelper;
38 import com.android.internal.util.FastXmlSerializer;
39 import com.android.internal.util.XmlUtils;
40 import com.android.server.DeviceStorageMonitorService;
41 import com.android.server.EventLogTags;
42 import com.android.server.IntentResolver;
44 import org.xmlpull.v1.XmlPullParser;
45 import org.xmlpull.v1.XmlPullParserException;
46 import org.xmlpull.v1.XmlSerializer;
48 import android.app.ActivityManager;
49 import android.app.ActivityManagerNative;
50 import android.app.IActivityManager;
51 import android.app.admin.IDevicePolicyManager;
52 import android.app.backup.IBackupManager;
53 import android.content.BroadcastReceiver;
54 import android.content.ComponentName;
55 import android.content.Context;
56 import android.content.IIntentReceiver;
57 import android.content.Intent;
58 import android.content.IntentFilter;
59 import android.content.IntentSender;
60 import android.content.ServiceConnection;
61 import android.content.IntentSender.SendIntentException;
62 import android.content.pm.ActivityInfo;
63 import android.content.pm.ApplicationInfo;
64 import android.content.pm.ContainerEncryptionParams;
65 import android.content.pm.FeatureInfo;
66 import android.content.pm.IPackageDataObserver;
67 import android.content.pm.IPackageDeleteObserver;
68 import android.content.pm.IPackageInstallObserver;
69 import android.content.pm.IPackageManager;
70 import android.content.pm.IPackageMoveObserver;
71 import android.content.pm.IPackageStatsObserver;
72 import android.content.pm.InstrumentationInfo;
73 import android.content.pm.PackageCleanItem;
74 import android.content.pm.PackageInfo;
75 import android.content.pm.PackageInfoLite;
76 import android.content.pm.PackageManager;
77 import android.content.pm.PackageParser;
78 import android.content.pm.PackageUserState;
79 import android.content.pm.PackageParser.ActivityIntentInfo;
80 import android.content.pm.PackageStats;
81 import android.content.pm.ParceledListSlice;
82 import android.content.pm.PermissionGroupInfo;
83 import android.content.pm.PermissionInfo;
84 import android.content.pm.ProviderInfo;
85 import android.content.pm.ResolveInfo;
86 import android.content.pm.ServiceInfo;
87 import android.content.pm.Signature;
88 import android.content.pm.ManifestDigest;
89 import android.content.pm.VerificationParams;
90 import android.content.pm.VerifierDeviceIdentity;
91 import android.content.pm.VerifierInfo;
92 import android.net.Uri;
93 import android.os.Binder;
94 import android.os.Build;
95 import android.os.Bundle;
96 import android.os.Environment;
97 import android.os.FileObserver;
98 import android.os.FileUtils;
99 import android.os.Handler;
100 import android.os.HandlerThread;
101 import android.os.IBinder;
102 import android.os.Looper;
103 import android.os.Message;
104 import android.os.Parcel;
105 import android.os.ParcelFileDescriptor;
106 import android.os.Process;
107 import android.os.RemoteException;
108 import android.os.SELinux;
109 import android.os.ServiceManager;
110 import android.os.SystemClock;
111 import android.os.SystemProperties;
112 import android.os.UserHandle;
113 import android.os.Environment.UserEnvironment;
114 import android.os.UserManager;
115 import android.provider.Settings.Secure;
116 import android.security.KeyStore;
117 import android.security.SystemKeyStore;
118 import android.util.DisplayMetrics;
119 import android.util.EventLog;
120 import android.util.Log;
121 import android.util.LogPrinter;
122 import android.util.Slog;
123 import android.util.SparseArray;
124 import android.util.Xml;
125 import android.view.Display;
126 import android.view.WindowManager;
128 import java.io.BufferedOutputStream;
130 import java.io.FileDescriptor;
131 import java.io.FileInputStream;
132 import java.io.FileNotFoundException;
133 import java.io.FileOutputStream;
134 import java.io.FileReader;
135 import java.io.FilenameFilter;
136 import java.io.IOException;
137 import java.io.ObjectOutputStream;
138 import java.io.PrintWriter;
139 import java.security.NoSuchAlgorithmException;
140 import java.security.PublicKey;
141 import java.security.cert.CertificateException;
142 import java.text.SimpleDateFormat;
143 import java.util.ArrayList;
144 import java.util.Arrays;
145 import java.util.Collection;
146 import java.util.Collections;
147 import java.util.Comparator;
148 import java.util.Date;
149 import java.util.HashMap;
150 import java.util.HashSet;
151 import java.util.Iterator;
152 import java.util.List;
153 import java.util.Map;
154 import java.util.Set;
156 import libcore.io.ErrnoException;
157 import libcore.io.IoUtils;
158 import libcore.io.Libcore;
159 import libcore.io.StructStat;
162 * Keep track of all those .apks everywhere.
164 * This is very central to the platform's security; please run the unit
165 * tests whenever making modifications here:
167 mmm frameworks/base/tests/AndroidTests
168 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
169 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
173 public class PackageManagerService extends IPackageManager.Stub {
174 static final String TAG = "PackageManager";
175 static final boolean DEBUG_SETTINGS = false;
176 static final boolean DEBUG_PREFERRED = false;
177 static final boolean DEBUG_UPGRADE = false;
178 private static final boolean DEBUG_INSTALL = false;
179 private static final boolean DEBUG_REMOVE = false;
180 private static final boolean DEBUG_BROADCASTS = false;
181 private static final boolean DEBUG_SHOW_INFO = false;
182 private static final boolean DEBUG_PACKAGE_INFO = false;
183 private static final boolean DEBUG_INTENT_MATCHING = false;
184 private static final boolean DEBUG_PACKAGE_SCANNING = false;
185 private static final boolean DEBUG_APP_DIR_OBSERVER = false;
186 private static final boolean DEBUG_VERIFY = false;
188 private static final int RADIO_UID = Process.PHONE_UID;
189 private static final int LOG_UID = Process.LOG_UID;
190 private static final int NFC_UID = Process.NFC_UID;
191 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
192 private static final int SHELL_UID = Process.SHELL_UID;
194 private static final boolean GET_CERTIFICATES = true;
196 private static final int REMOVE_EVENTS =
197 FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
198 private static final int ADD_EVENTS =
199 FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
201 private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
202 // Suffix used during package installation when copying/moving
203 // package apks to install directory.
204 private static final String INSTALL_PACKAGE_SUFFIX = "-";
206 static final int SCAN_MONITOR = 1<<0;
207 static final int SCAN_NO_DEX = 1<<1;
208 static final int SCAN_FORCE_DEX = 1<<2;
209 static final int SCAN_UPDATE_SIGNATURE = 1<<3;
210 static final int SCAN_NEW_INSTALL = 1<<4;
211 static final int SCAN_NO_PATHS = 1<<5;
212 static final int SCAN_UPDATE_TIME = 1<<6;
213 static final int SCAN_DEFER_DEX = 1<<7;
214 static final int SCAN_BOOTING = 1<<8;
216 static final int REMOVE_CHATTY = 1<<16;
219 * Whether verification is enabled by default.
221 private static final boolean DEFAULT_VERIFY_ENABLE = true;
224 * The default maximum time to wait for the verification agent to return in
227 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
230 * The default response for package verification timeout.
232 * This can be either PackageManager.VERIFICATION_ALLOW or
233 * PackageManager.VERIFICATION_REJECT.
235 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
237 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
239 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
240 DEFAULT_CONTAINER_PACKAGE,
241 "com.android.defcontainer.DefaultContainerService");
243 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
245 private static final String LIB_DIR_NAME = "lib";
247 static final String mTempContainerPrefix = "smdl2tmp";
249 final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
250 Process.THREAD_PRIORITY_BACKGROUND);
251 final PackageHandler mHandler;
253 final int mSdkVersion = Build.VERSION.SDK_INT;
254 final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
255 ? null : Build.VERSION.CODENAME;
257 final Context mContext;
258 final boolean mFactoryTest;
259 final boolean mOnlyCore;
260 final boolean mNoDexOpt;
261 final DisplayMetrics mMetrics;
262 final int mDefParseFlags;
263 final String[] mSeparateProcesses;
265 // This is where all application persistent data goes.
266 final File mAppDataDir;
268 // This is where all application persistent data goes for secondary users.
269 final File mUserAppDataDir;
271 /** The location for ASEC container files on internal storage. */
272 final String mAsecInternalPath;
274 // This is the object monitoring the framework dir.
275 final FileObserver mFrameworkInstallObserver;
277 // This is the object monitoring the system app dir.
278 final FileObserver mSystemInstallObserver;
280 // This is the object monitoring the system app dir.
281 final FileObserver mVendorInstallObserver;
283 // This is the object monitoring mAppInstallDir.
284 final FileObserver mAppInstallObserver;
286 // This is the object monitoring mDrmAppPrivateInstallDir.
287 final FileObserver mDrmAppInstallObserver;
289 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
290 // LOCK HELD. Can be called with mInstallLock held.
291 final Installer mInstaller;
293 final File mFrameworkDir;
294 final File mSystemAppDir;
295 final File mVendorAppDir;
296 final File mAppInstallDir;
297 final File mDalvikCacheDir;
300 * Directory to which applications installed internally have native
303 private File mAppLibInstallDir;
305 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
307 final File mDrmAppPrivateInstallDir;
309 // ----------------------------------------------------------------
311 // Lock for state used when installing and doing other long running
312 // operations. Methods that must be called with this lock held have
314 final Object mInstallLock = new Object();
316 // These are the directories in the 3rd party applications installed dir
317 // that we have currently loaded packages from. Keys are the application's
318 // installed zip file (absolute codePath), and values are Package.
319 final HashMap<String, PackageParser.Package> mAppDirs =
320 new HashMap<String, PackageParser.Package>();
322 // Information for the parser to write more useful error messages.
326 // ----------------------------------------------------------------
328 // Keys are String (package name), values are Package. This also serves
329 // as the lock for the global state. Methods that must be called with
330 // this lock held have the prefix "LP".
331 final HashMap<String, PackageParser.Package> mPackages =
332 new HashMap<String, PackageParser.Package>();
334 final Settings mSettings;
335 boolean mRestoredSettings;
337 // Group-ids that are given to all packages as read from etc/permissions/*.xml.
340 // These are the built-in uid -> permission mappings that were read from the
341 // etc/permissions.xml file.
342 final SparseArray<HashSet<String>> mSystemPermissions =
343 new SparseArray<HashSet<String>>();
345 static final class SharedLibraryEntry {
349 SharedLibraryEntry(String _path, String _apk) {
355 // These are the built-in shared libraries that were read from the
356 // etc/permissions.xml file.
357 final HashMap<String, SharedLibraryEntry> mSharedLibraries
358 = new HashMap<String, SharedLibraryEntry>();
360 // Temporary for building the final shared libraries for an .apk.
361 String[] mTmpSharedLibraries = null;
363 // These are the features this devices supports that were read from the
364 // etc/permissions.xml file.
365 final HashMap<String, FeatureInfo> mAvailableFeatures =
366 new HashMap<String, FeatureInfo>();
368 // If mac_permissions.xml was found for seinfo labeling.
369 boolean mFoundPolicyFile;
371 // All available activities, for your resolving pleasure.
372 final ActivityIntentResolver mActivities =
373 new ActivityIntentResolver();
375 // All available receivers, for your resolving pleasure.
376 final ActivityIntentResolver mReceivers =
377 new ActivityIntentResolver();
379 // All available services, for your resolving pleasure.
380 final ServiceIntentResolver mServices = new ServiceIntentResolver();
382 // Keys are String (provider class name), values are Provider.
383 final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =
384 new HashMap<ComponentName, PackageParser.Provider>();
386 // Mapping from provider base names (first directory in content URI codePath)
387 // to the provider information.
388 final HashMap<String, PackageParser.Provider> mProviders =
389 new HashMap<String, PackageParser.Provider>();
391 // Mapping from instrumentation class names to info about them.
392 final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
393 new HashMap<ComponentName, PackageParser.Instrumentation>();
395 // Mapping from permission names to info about them.
396 final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
397 new HashMap<String, PackageParser.PermissionGroup>();
399 // Packages whose data we have transfered into another package, thus
400 // should no longer exist.
401 final HashSet<String> mTransferedPackages = new HashSet<String>();
403 // Broadcast actions that are only available to the system.
404 final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
406 /** List of packages waiting for verification. */
407 final SparseArray<PackageVerificationState> mPendingVerification
408 = new SparseArray<PackageVerificationState>();
410 HashSet<PackageParser.Package> mDeferredDexOpt = null;
412 /** Token for keys in mPendingVerification. */
413 private int mPendingVerificationToken = 0;
415 boolean mSystemReady;
417 boolean mHasSystemUidErrors;
419 ApplicationInfo mAndroidApplication;
420 final ActivityInfo mResolveActivity = new ActivityInfo();
421 final ResolveInfo mResolveInfo = new ResolveInfo();
422 ComponentName mResolveComponentName;
423 PackageParser.Package mPlatformPackage;
425 // Set of pending broadcasts for aggregating enable/disable of components.
426 static class PendingPackageBroadcasts {
427 // for each user id, a map of <package name -> components within that package>
428 final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
430 public PendingPackageBroadcasts() {
431 mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>();
434 public ArrayList<String> get(int userId, String packageName) {
435 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
436 return packages.get(packageName);
439 public void put(int userId, String packageName, ArrayList<String> components) {
440 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
441 packages.put(packageName, components);
444 public void remove(int userId, String packageName) {
445 HashMap<String, ArrayList<String>> packages = mUidMap.get(userId);
446 if (packages != null) {
447 packages.remove(packageName);
451 public void remove(int userId) {
452 mUidMap.remove(userId);
455 public int userIdCount() {
456 return mUidMap.size();
459 public int userIdAt(int n) {
460 return mUidMap.keyAt(n);
463 public HashMap<String, ArrayList<String>> packagesForUserId(int userId) {
464 return mUidMap.get(userId);
468 // total number of pending broadcast entries across all userIds
470 for (int i = 0; i< mUidMap.size(); i++) {
471 num += mUidMap.valueAt(i).size();
476 public void clear() {
480 private HashMap<String, ArrayList<String>> getOrAllocate(int userId) {
481 HashMap<String, ArrayList<String>> map = mUidMap.get(userId);
483 map = new HashMap<String, ArrayList<String>>();
484 mUidMap.put(userId, map);
489 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
491 // Service Connection to remote media container service to copy
492 // package uri's from external media onto secure containers
493 // or internal storage.
494 private IMediaContainerService mContainerService = null;
496 // Packages that have been installed with library matching 2nd ABI.
497 final HashMap<Integer, String> mPackagesMatchABI2 = new HashMap<Integer,String>();
498 // Packages that have been installed with library matching 2nd ABI and matching neon app list
499 final HashMap<Integer, String> mPackagesMatchABI2Neon = new HashMap<Integer,String>();
501 static final int SEND_PENDING_BROADCAST = 1;
502 static final int MCS_BOUND = 3;
503 static final int END_COPY = 4;
504 static final int INIT_COPY = 5;
505 static final int MCS_UNBIND = 6;
506 static final int START_CLEANING_PACKAGE = 7;
507 static final int FIND_INSTALL_LOC = 8;
508 static final int POST_INSTALL = 9;
509 static final int MCS_RECONNECT = 10;
510 static final int MCS_GIVE_UP = 11;
511 static final int UPDATED_MEDIA_STATUS = 12;
512 static final int WRITE_SETTINGS = 13;
513 static final int WRITE_PACKAGE_RESTRICTIONS = 14;
514 static final int PACKAGE_VERIFIED = 15;
515 static final int CHECK_PENDING_VERIFICATION = 16;
517 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds
519 // Delay time in millisecs
520 static final int BROADCAST_DELAY = 10 * 1000;
522 static UserManagerService sUserManager;
524 // Stores a list of users whose package restrictions file needs to be updated
525 private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
527 final private DefaultContainerConnection mDefContainerConn =
528 new DefaultContainerConnection();
529 class DefaultContainerConnection implements ServiceConnection {
530 public void onServiceConnected(ComponentName name, IBinder service) {
531 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
532 IMediaContainerService imcs =
533 IMediaContainerService.Stub.asInterface(service);
534 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
537 public void onServiceDisconnected(ComponentName name) {
538 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
542 // Recordkeeping of restore-after-install operations that are currently in flight
543 // between the Package Manager and the Backup Manager
544 class PostInstallData {
545 public InstallArgs args;
546 public PackageInstalledInfo res;
548 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
553 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
554 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
556 private final String mRequiredVerifierPackage;
558 class PackageHandler extends Handler {
559 private boolean mBound = false;
560 final ArrayList<HandlerParams> mPendingInstalls =
561 new ArrayList<HandlerParams>();
563 private boolean connectToService() {
564 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
565 " DefaultContainerService");
566 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
567 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
568 if (mContext.bindServiceAsUser(service, mDefContainerConn,
569 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
570 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
574 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
578 private void disconnectService() {
579 mContainerService = null;
581 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
582 mContext.unbindService(mDefContainerConn);
583 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
586 PackageHandler(Looper looper) {
590 public void handleMessage(Message msg) {
592 doHandleMessage(msg);
594 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
598 void doHandleMessage(Message msg) {
601 HandlerParams params = (HandlerParams) msg.obj;
602 int idx = mPendingInstalls.size();
603 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
604 // If a bind was already initiated we dont really
605 // need to do anything. The pending install
606 // will be processed later on.
608 // If this is the only one pending we might
609 // have to bind to the service again.
610 if (!connectToService()) {
611 Slog.e(TAG, "Failed to bind to media container service");
612 params.serviceError();
615 // Once we bind to the service, the first
616 // pending request will be processed.
617 mPendingInstalls.add(idx, params);
620 mPendingInstalls.add(idx, params);
621 // Already bound to the service. Just make
622 // sure we trigger off processing the first request.
624 mHandler.sendEmptyMessage(MCS_BOUND);
630 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
631 if (msg.obj != null) {
632 mContainerService = (IMediaContainerService) msg.obj;
634 if (mContainerService == null) {
635 // Something seriously wrong. Bail out
636 Slog.e(TAG, "Cannot bind to media container service");
637 for (HandlerParams params : mPendingInstalls) {
638 // Indicate service bind error
639 params.serviceError();
641 mPendingInstalls.clear();
642 } else if (mPendingInstalls.size() > 0) {
643 HandlerParams params = mPendingInstalls.get(0);
644 if (params != null) {
645 if (params.startCopy()) {
646 // We are done... look for more work or to
648 if (DEBUG_SD_INSTALL) Log.i(TAG,
649 "Checking for more work or unbind...");
650 // Delete pending install
651 if (mPendingInstalls.size() > 0) {
652 mPendingInstalls.remove(0);
654 if (mPendingInstalls.size() == 0) {
656 if (DEBUG_SD_INSTALL) Log.i(TAG,
657 "Posting delayed MCS_UNBIND");
658 removeMessages(MCS_UNBIND);
659 Message ubmsg = obtainMessage(MCS_UNBIND);
660 // Unbind after a little delay, to avoid
661 // continual thrashing.
662 sendMessageDelayed(ubmsg, 10000);
665 // There are more pending requests in queue.
666 // Just post MCS_BOUND message to trigger processing
667 // of next pending install.
668 if (DEBUG_SD_INSTALL) Log.i(TAG,
669 "Posting MCS_BOUND for next woek");
670 mHandler.sendEmptyMessage(MCS_BOUND);
675 // Should never happen ideally.
676 Slog.w(TAG, "Empty queue");
680 case MCS_RECONNECT: {
681 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
682 if (mPendingInstalls.size() > 0) {
686 if (!connectToService()) {
687 Slog.e(TAG, "Failed to bind to media container service");
688 for (HandlerParams params : mPendingInstalls) {
689 // Indicate service bind error
690 params.serviceError();
692 mPendingInstalls.clear();
698 // If there is no actual work left, then time to unbind.
699 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
701 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
703 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
707 } else if (mPendingInstalls.size() > 0) {
708 // There are more pending requests in queue.
709 // Just post MCS_BOUND message to trigger processing
710 // of next pending install.
711 mHandler.sendEmptyMessage(MCS_BOUND);
717 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
718 mPendingInstalls.remove(0);
721 case SEND_PENDING_BROADCAST: {
723 ArrayList<String> components[];
726 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
727 synchronized (mPackages) {
728 if (mPendingBroadcasts == null) {
731 size = mPendingBroadcasts.size();
733 // Nothing to be done. Just return
736 packages = new String[size];
737 components = new ArrayList[size];
738 uids = new int[size];
739 int i = 0; // filling out the above arrays
741 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
742 int packageUserId = mPendingBroadcasts.userIdAt(n);
743 Iterator<Map.Entry<String, ArrayList<String>>> it
744 = mPendingBroadcasts.packagesForUserId(packageUserId)
745 .entrySet().iterator();
746 while (it.hasNext() && i < size) {
747 Map.Entry<String, ArrayList<String>> ent = it.next();
748 packages[i] = ent.getKey();
749 components[i] = ent.getValue();
750 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
751 uids[i] = (ps != null)
752 ? UserHandle.getUid(packageUserId, ps.appId)
758 mPendingBroadcasts.clear();
761 for (int i = 0; i < size; i++) {
762 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
764 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
767 case START_CLEANING_PACKAGE: {
768 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
769 final String packageName = (String)msg.obj;
770 final int userId = msg.arg1;
771 final boolean andCode = msg.arg2 != 0;
772 synchronized (mPackages) {
773 if (userId == UserHandle.USER_ALL) {
774 int[] users = sUserManager.getUserIds();
775 for (int user : users) {
776 mSettings.addPackageToCleanLPw(
777 new PackageCleanItem(user, packageName, andCode));
780 mSettings.addPackageToCleanLPw(
781 new PackageCleanItem(userId, packageName, andCode));
784 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
785 startCleaningPackages();
788 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
789 PostInstallData data = mRunningInstalls.get(msg.arg1);
790 mRunningInstalls.delete(msg.arg1);
791 boolean deleteOld = false;
794 InstallArgs args = data.args;
795 PackageInstalledInfo res = data.res;
797 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
798 res.removedInfo.sendBroadcast(false, true, false);
799 Bundle extras = new Bundle(1);
800 extras.putInt(Intent.EXTRA_UID, res.uid);
801 // Determine the set of users who are adding this
802 // package for the first time vs. those who are seeing
805 int[] updateUsers = new int[0];
806 if (res.origUsers == null || res.origUsers.length == 0) {
807 firstUsers = res.newUsers;
809 firstUsers = new int[0];
810 for (int i=0; i<res.newUsers.length; i++) {
811 int user = res.newUsers[i];
812 boolean isNew = true;
813 for (int j=0; j<res.origUsers.length; j++) {
814 if (res.origUsers[j] == user) {
820 int[] newFirst = new int[firstUsers.length+1];
821 System.arraycopy(firstUsers, 0, newFirst, 0,
823 newFirst[firstUsers.length] = user;
824 firstUsers = newFirst;
826 int[] newUpdate = new int[updateUsers.length+1];
827 System.arraycopy(updateUsers, 0, newUpdate, 0,
829 newUpdate[updateUsers.length] = user;
830 updateUsers = newUpdate;
834 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
835 res.pkg.applicationInfo.packageName,
836 extras, null, null, firstUsers);
837 final boolean update = res.removedInfo.removedPackage != null;
839 extras.putBoolean(Intent.EXTRA_REPLACING, true);
841 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
842 res.pkg.applicationInfo.packageName,
843 extras, null, null, updateUsers);
845 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
846 res.pkg.applicationInfo.packageName,
847 extras, null, null, updateUsers);
848 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
850 res.pkg.applicationInfo.packageName, null, updateUsers);
852 if (res.removedInfo.args != null) {
853 // Remove the replaced package's older resources safely now
857 // Log current value of "unknown sources" setting
858 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
859 getUnknownSourcesSettings());
861 // Force a gc to clear up things
862 Runtime.getRuntime().gc();
863 // We delete after a gc for applications on sdcard.
865 synchronized (mInstallLock) {
866 res.removedInfo.args.doPostDeleteLI(true);
869 if (args.observer != null) {
871 args.observer.packageInstalled(res.name, res.returnCode);
872 } catch (RemoteException e) {
873 Slog.i(TAG, "Observer no longer exists.");
877 Slog.e(TAG, "Bogus post-install token " + msg.arg1);
880 case UPDATED_MEDIA_STATUS: {
881 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
882 boolean reportStatus = msg.arg1 == 1;
883 boolean doGc = msg.arg2 == 1;
884 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
886 // Force a gc to clear up stale containers.
887 Runtime.getRuntime().gc();
889 if (msg.obj != null) {
890 @SuppressWarnings("unchecked")
891 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
892 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
894 unloadAllContainers(args);
898 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
899 PackageHelper.getMountService().finishMediaUpdate();
900 } catch (RemoteException e) {
901 Log.e(TAG, "MountService not running?");
905 case WRITE_SETTINGS: {
906 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
907 synchronized (mPackages) {
908 removeMessages(WRITE_SETTINGS);
909 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
910 mSettings.writeLPr();
913 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
915 case WRITE_PACKAGE_RESTRICTIONS: {
916 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
917 synchronized (mPackages) {
918 removeMessages(WRITE_PACKAGE_RESTRICTIONS);
919 for (int userId : mDirtyUsers) {
920 mSettings.writePackageRestrictionsLPr(userId);
924 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
926 case CHECK_PENDING_VERIFICATION: {
927 final int verificationId = msg.arg1;
928 final PackageVerificationState state = mPendingVerification.get(verificationId);
930 if ((state != null) && !state.timeoutExtended()) {
931 final InstallArgs args = state.getInstallArgs();
932 Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
933 mPendingVerification.remove(verificationId);
935 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
937 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
938 Slog.i(TAG, "Continuing with installation of "
939 + args.packageURI.toString());
940 state.setVerifierResponse(Binder.getCallingUid(),
941 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
942 broadcastPackageVerified(verificationId, args.packageURI,
943 PackageManager.VERIFICATION_ALLOW,
944 state.getInstallArgs().getUser());
946 ret = args.copyApk(mContainerService, true);
947 } catch (RemoteException e) {
948 Slog.e(TAG, "Could not contact the ContainerService");
951 broadcastPackageVerified(verificationId, args.packageURI,
952 PackageManager.VERIFICATION_REJECT,
953 state.getInstallArgs().getUser());
956 processPendingInstall(args, ret);
957 mHandler.sendEmptyMessage(MCS_UNBIND);
961 case PACKAGE_VERIFIED: {
962 final int verificationId = msg.arg1;
964 final PackageVerificationState state = mPendingVerification.get(verificationId);
966 Slog.w(TAG, "Invalid verification token " + verificationId + " received");
970 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
972 state.setVerifierResponse(response.callerUid, response.code);
974 if (state.isVerificationComplete()) {
975 mPendingVerification.remove(verificationId);
977 final InstallArgs args = state.getInstallArgs();
980 if (state.isInstallAllowed()) {
981 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
982 broadcastPackageVerified(verificationId, args.packageURI,
983 response.code, state.getInstallArgs().getUser());
985 ret = args.copyApk(mContainerService, true);
986 } catch (RemoteException e) {
987 Slog.e(TAG, "Could not contact the ContainerService");
990 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
993 processPendingInstall(args, ret);
995 mHandler.sendEmptyMessage(MCS_UNBIND);
1004 void scheduleWriteSettingsLocked() {
1005 if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1006 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1010 void scheduleWritePackageRestrictionsLocked(int userId) {
1011 if (!sUserManager.exists(userId)) return;
1012 mDirtyUsers.add(userId);
1013 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1014 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1018 public static final IPackageManager main(Context context, Installer installer,
1019 boolean factoryTest, boolean onlyCore) {
1020 PackageManagerService m = new PackageManagerService(context, installer,
1021 factoryTest, onlyCore);
1022 ServiceManager.addService("package", m);
1026 static String[] splitString(String str, char sep) {
1029 while ((i=str.indexOf(sep, i)) >= 0) {
1034 String[] res = new String[count];
1038 while ((i=str.indexOf(sep, i)) >= 0) {
1039 res[count] = str.substring(lastI, i);
1044 res[count] = str.substring(lastI, str.length());
1048 public PackageManagerService(Context context, Installer installer,
1049 boolean factoryTest, boolean onlyCore) {
1050 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1051 SystemClock.uptimeMillis());
1053 if (mSdkVersion <= 0) {
1054 Slog.w(TAG, "**** ro.build.version.sdk not set!");
1058 mFactoryTest = factoryTest;
1059 mOnlyCore = onlyCore;
1060 mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1061 mMetrics = new DisplayMetrics();
1062 mSettings = new Settings(context);
1063 mSettings.addSharedUserLPw("android.uid.system",
1064 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
1065 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
1066 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
1067 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
1068 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
1069 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, ApplicationInfo.FLAG_SYSTEM);
1071 String separateProcesses = SystemProperties.get("debug.separate_processes");
1072 if (separateProcesses != null && separateProcesses.length() > 0) {
1073 if ("*".equals(separateProcesses)) {
1074 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1075 mSeparateProcesses = null;
1076 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1079 mSeparateProcesses = separateProcesses.split(",");
1080 Slog.w(TAG, "Running with debug.separate_processes: "
1081 + separateProcesses);
1085 mSeparateProcesses = null;
1088 mInstaller = installer;
1090 WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
1091 Display d = wm.getDefaultDisplay();
1092 d.getMetrics(mMetrics);
1094 synchronized (mInstallLock) {
1096 synchronized (mPackages) {
1097 mHandlerThread.start();
1098 mHandler = new PackageHandler(mHandlerThread.getLooper());
1100 File dataDir = Environment.getDataDirectory();
1101 mAppDataDir = new File(dataDir, "data");
1102 mAppInstallDir = new File(dataDir, "app");
1103 mAppLibInstallDir = new File(dataDir, "app-lib");
1104 mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1105 mUserAppDataDir = new File(dataDir, "user");
1106 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1108 sUserManager = new UserManagerService(context, this,
1109 mInstallLock, mPackages);
1113 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1115 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1116 mSdkVersion, mOnlyCore);
1118 long startTime = SystemClock.uptimeMillis();
1120 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1123 // Set flag to monitor and not change apk file paths when
1124 // scanning install directories.
1125 int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1127 Slog.w(TAG, "Running ENG build: no pre-dexopt!");
1128 scanMode |= SCAN_NO_DEX;
1131 final HashSet<String> libFiles = new HashSet<String>();
1133 mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
1134 mDalvikCacheDir = new File(dataDir, "dalvik-cache");
1136 boolean didDexOpt = false;
1139 * Out of paranoia, ensure that everything in the boot class
1140 * path has been dexed.
1142 String bootClassPath = System.getProperty("java.boot.class.path");
1143 if (bootClassPath != null) {
1144 String[] paths = splitString(bootClassPath, ':');
1145 for (int i=0; i<paths.length; i++) {
1147 if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
1148 libFiles.add(paths[i]);
1149 mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
1152 } catch (FileNotFoundException e) {
1153 Slog.w(TAG, "Boot class path not found: " + paths[i]);
1154 } catch (IOException e) {
1155 Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
1160 Slog.w(TAG, "No BOOTCLASSPATH found!");
1164 * Also ensure all external libraries have had dexopt run on them.
1166 if (mSharedLibraries.size() > 0) {
1167 Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator();
1168 while (libs.hasNext()) {
1169 String lib = libs.next().path;
1174 if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
1176 mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
1179 } catch (FileNotFoundException e) {
1180 Slog.w(TAG, "Library not found: " + lib);
1181 } catch (IOException e) {
1182 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1188 // Gross hack for now: we know this file doesn't contain any
1189 // code, so don't dexopt it to avoid the resulting log spew.
1190 libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
1193 * And there are a number of commands implemented in Java, which
1194 * we currently need to do the dexopt on so that they can be
1195 * run from a non-root shell.
1197 String[] frameworkFiles = mFrameworkDir.list();
1198 if (frameworkFiles != null) {
1199 for (int i=0; i<frameworkFiles.length; i++) {
1200 File libPath = new File(mFrameworkDir, frameworkFiles[i]);
1201 String path = libPath.getPath();
1202 // Skip the file if we alrady did it.
1203 if (libFiles.contains(path)) {
1206 // Skip the file if it is not a type we want to dexopt.
1207 if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1211 if (dalvik.system.DexFile.isDexOptNeeded(path)) {
1212 mInstaller.dexopt(path, Process.SYSTEM_UID, true);
1215 } catch (FileNotFoundException e) {
1216 Slog.w(TAG, "Jar not found: " + path);
1217 } catch (IOException e) {
1218 Slog.w(TAG, "Exception reading jar: " + path, e);
1224 // If we had to do a dexopt of one of the previous
1225 // things, then something on the system has changed.
1226 // Consider this significant, and wipe away all other
1227 // existing dexopt files to ensure we don't leave any
1229 String[] files = mDalvikCacheDir.list();
1230 if (files != null) {
1231 for (int i=0; i<files.length; i++) {
1232 String fn = files[i];
1233 if (fn.startsWith("data@app@")
1234 || fn.startsWith("data@app-private@")) {
1235 Slog.i(TAG, "Pruning dalvik file: " + fn);
1236 (new File(mDalvikCacheDir, fn)).delete();
1242 // Find base frameworks (resource packages without code).
1243 mFrameworkInstallObserver = new AppDirObserver(
1244 mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
1245 mFrameworkInstallObserver.startWatching();
1246 scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
1247 | PackageParser.PARSE_IS_SYSTEM_DIR,
1248 scanMode | SCAN_NO_DEX, 0);
1250 // Collect all system packages.
1251 mSystemAppDir = new File(Environment.getRootDirectory(), "app");
1252 mSystemInstallObserver = new AppDirObserver(
1253 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
1254 mSystemInstallObserver.startWatching();
1255 scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
1256 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1258 // Collect all vendor packages.
1259 mVendorAppDir = new File("/vendor/app");
1260 mVendorInstallObserver = new AppDirObserver(
1261 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
1262 mVendorInstallObserver.startWatching();
1263 scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
1264 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1266 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1267 mInstaller.moveFiles();
1269 // Prune any system packages that no longer exist.
1270 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1272 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1273 while (psit.hasNext()) {
1274 PackageSetting ps = psit.next();
1277 * If this is not a system app, it can't be a
1278 * disable system app.
1280 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1285 * If the package is scanned, it's not erased.
1287 final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1288 if (scannedPkg != null) {
1290 * If the system app is both scanned and in the
1291 * disabled packages list, then it must have been
1292 * added via OTA. Remove it from the currently
1293 * scanned package so the previously user-installed
1294 * application can be scanned.
1296 if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1297 Slog.i(TAG, "Expecting better updatd system app for " + ps.name
1298 + "; removing system app");
1299 removePackageLI(ps, true);
1305 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1307 String msg = "System package " + ps.name
1308 + " no longer exists; wiping its data";
1309 reportSettingsProblem(Log.WARN, msg);
1310 removeDataDirsLI(ps.name);
1312 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1313 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1314 possiblyDeletedUpdatedSystemApps.add(ps.name);
1320 //look for any incomplete package installations
1321 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1323 for(int i = 0; i < deletePkgsList.size(); i++) {
1325 cleanupInstallFailedPackage(deletePkgsList.get(i));
1328 deleteTempPackageFiles();
1331 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1332 SystemClock.uptimeMillis());
1333 mAppInstallObserver = new AppDirObserver(
1334 mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
1335 mAppInstallObserver.startWatching();
1336 scanDirLI(mAppInstallDir, 0, scanMode, 0);
1338 mDrmAppInstallObserver = new AppDirObserver(
1339 mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
1340 mDrmAppInstallObserver.startWatching();
1341 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1345 * Remove disable package settings for any updated system
1346 * apps that were removed via an OTA. If they're not a
1347 * previously-updated app, remove them completely.
1348 * Otherwise, just revoke their system-level permissions.
1350 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1351 PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1352 mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1355 if (deletedPkg == null) {
1356 msg = "Updated system package " + deletedAppName
1357 + " no longer exists; wiping its data";
1358 removeDataDirsLI(deletedAppName);
1360 msg = "Updated system app + " + deletedAppName
1361 + " no longer present; removing system privileges for "
1364 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1366 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1367 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1369 reportSettingsProblem(Log.WARN, msg);
1372 mAppInstallObserver = null;
1373 mDrmAppInstallObserver = null;
1376 // Now that we know all of the shared libraries, update all clients to have
1377 // the correct library paths.
1378 updateAllSharedLibrariesLPw();
1380 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1381 SystemClock.uptimeMillis());
1382 Slog.i(TAG, "Time to scan packages: "
1383 + ((SystemClock.uptimeMillis()-startTime)/1000f)
1386 // If the platform SDK has changed since the last time we booted,
1387 // we need to re-grant app permission to catch any new ones that
1388 // appear. This is really a hack, and means that apps can in some
1389 // cases get permissions that the user didn't initially explicitly
1390 // allow... it would be nice to have some better way to handle
1392 final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1394 if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1395 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1396 + "; regranting permissions for internal storage");
1397 mSettings.mInternalSdkPlatform = mSdkVersion;
1399 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1400 | (regrantPermissions
1401 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1404 // If this is the first boot, and it is a normal boot, then
1405 // we need to initialize the default preferred apps.
1406 if (!mRestoredSettings && !onlyCore) {
1407 mSettings.readDefaultPreferredAppsLPw(this, 0);
1410 // can downgrade to reader
1411 mSettings.writeLPr();
1413 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1414 SystemClock.uptimeMillis());
1416 // Now after opening every single application zip, make sure they
1417 // are all flushed. Not really needed, but keeps things nice and
1419 Runtime.getRuntime().gc();
1421 mRequiredVerifierPackage = getRequiredVerifierLPr();
1422 } // synchronized (mPackages)
1423 } // synchronized (mInstallLock)
1426 public boolean isFirstBoot() {
1427 return !mRestoredSettings;
1430 public boolean isOnlyCoreApps() {
1434 private String getRequiredVerifierLPr() {
1435 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1436 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1437 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1439 String requiredVerifier = null;
1441 final int N = receivers.size();
1442 for (int i = 0; i < N; i++) {
1443 final ResolveInfo info = receivers.get(i);
1445 if (info.activityInfo == null) {
1449 final String packageName = info.activityInfo.packageName;
1451 final PackageSetting ps = mSettings.mPackages.get(packageName);
1456 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1457 if (!gp.grantedPermissions
1458 .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1462 if (requiredVerifier != null) {
1463 throw new RuntimeException("There can be only one required verifier");
1466 requiredVerifier = packageName;
1469 return requiredVerifier;
1473 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1474 throws RemoteException {
1476 return super.onTransact(code, data, reply, flags);
1477 } catch (RuntimeException e) {
1478 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1479 Slog.e(TAG, "Package Manager Crash", e);
1485 void cleanupInstallFailedPackage(PackageSetting ps) {
1486 Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
1487 removeDataDirsLI(ps.name);
1488 if (ps.codePath != null) {
1489 if (!ps.codePath.delete()) {
1490 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
1493 if (ps.resourcePath != null) {
1494 if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
1495 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
1498 mSettings.removePackageLPw(ps.name);
1501 void readPermissions() {
1502 // Read permissions from .../etc/permission directory.
1503 File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
1504 if (!libraryDir.exists() || !libraryDir.isDirectory()) {
1505 Slog.w(TAG, "No directory " + libraryDir + ", skipping");
1508 if (!libraryDir.canRead()) {
1509 Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
1513 // Iterate over the files in the directory and scan .xml files
1514 for (File f : libraryDir.listFiles()) {
1515 // We'll read platform.xml last
1516 if (f.getPath().endsWith("etc/permissions/platform.xml")) {
1520 if (!f.getPath().endsWith(".xml")) {
1521 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
1525 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
1529 readPermissionsFromXml(f);
1532 // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
1533 final File permFile = new File(Environment.getRootDirectory(),
1534 "etc/permissions/platform.xml");
1535 readPermissionsFromXml(permFile);
1538 private void readPermissionsFromXml(File permFile) {
1539 FileReader permReader = null;
1541 permReader = new FileReader(permFile);
1542 } catch (FileNotFoundException e) {
1543 Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
1548 XmlPullParser parser = Xml.newPullParser();
1549 parser.setInput(permReader);
1551 XmlUtils.beginDocument(parser, "permissions");
1554 XmlUtils.nextElement(parser);
1555 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
1559 String name = parser.getName();
1560 if ("group".equals(name)) {
1561 String gidStr = parser.getAttributeValue(null, "gid");
1562 if (gidStr != null) {
1563 int gid = Process.getGidForName(gidStr);
1564 mGlobalGids = appendInt(mGlobalGids, gid);
1566 Slog.w(TAG, "<group> without gid at "
1567 + parser.getPositionDescription());
1570 XmlUtils.skipCurrentTag(parser);
1572 } else if ("permission".equals(name)) {
1573 String perm = parser.getAttributeValue(null, "name");
1575 Slog.w(TAG, "<permission> without name at "
1576 + parser.getPositionDescription());
1577 XmlUtils.skipCurrentTag(parser);
1580 perm = perm.intern();
1581 readPermission(parser, perm);
1583 } else if ("assign-permission".equals(name)) {
1584 String perm = parser.getAttributeValue(null, "name");
1586 Slog.w(TAG, "<assign-permission> without name at "
1587 + parser.getPositionDescription());
1588 XmlUtils.skipCurrentTag(parser);
1591 String uidStr = parser.getAttributeValue(null, "uid");
1592 if (uidStr == null) {
1593 Slog.w(TAG, "<assign-permission> without uid at "
1594 + parser.getPositionDescription());
1595 XmlUtils.skipCurrentTag(parser);
1598 int uid = Process.getUidForName(uidStr);
1600 Slog.w(TAG, "<assign-permission> with unknown uid \""
1602 + parser.getPositionDescription());
1603 XmlUtils.skipCurrentTag(parser);
1606 perm = perm.intern();
1607 HashSet<String> perms = mSystemPermissions.get(uid);
1608 if (perms == null) {
1609 perms = new HashSet<String>();
1610 mSystemPermissions.put(uid, perms);
1613 XmlUtils.skipCurrentTag(parser);
1615 } else if ("library".equals(name)) {
1616 String lname = parser.getAttributeValue(null, "name");
1617 String lfile = parser.getAttributeValue(null, "file");
1618 if (lname == null) {
1619 Slog.w(TAG, "<library> without name at "
1620 + parser.getPositionDescription());
1621 } else if (lfile == null) {
1622 Slog.w(TAG, "<library> without file at "
1623 + parser.getPositionDescription());
1625 //Log.i(TAG, "Got library " + lname + " in " + lfile);
1626 mSharedLibraries.put(lname, new SharedLibraryEntry(lfile, null));
1628 XmlUtils.skipCurrentTag(parser);
1631 } else if ("feature".equals(name)) {
1632 String fname = parser.getAttributeValue(null, "name");
1633 if (fname == null) {
1634 Slog.w(TAG, "<feature> without name at "
1635 + parser.getPositionDescription());
1637 //Log.i(TAG, "Got feature " + fname);
1638 FeatureInfo fi = new FeatureInfo();
1640 mAvailableFeatures.put(fname, fi);
1642 XmlUtils.skipCurrentTag(parser);
1646 XmlUtils.skipCurrentTag(parser);
1652 } catch (XmlPullParserException e) {
1653 Slog.w(TAG, "Got execption parsing permissions.", e);
1654 } catch (IOException e) {
1655 Slog.w(TAG, "Got execption parsing permissions.", e);
1659 void readPermission(XmlPullParser parser, String name)
1660 throws IOException, XmlPullParserException {
1662 name = name.intern();
1664 BasePermission bp = mSettings.mPermissions.get(name);
1666 bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
1667 mSettings.mPermissions.put(name, bp);
1669 int outerDepth = parser.getDepth();
1671 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1672 && (type != XmlPullParser.END_TAG
1673 || parser.getDepth() > outerDepth)) {
1674 if (type == XmlPullParser.END_TAG
1675 || type == XmlPullParser.TEXT) {
1679 String tagName = parser.getName();
1680 if ("group".equals(tagName)) {
1681 String gidStr = parser.getAttributeValue(null, "gid");
1682 if (gidStr != null) {
1683 int gid = Process.getGidForName(gidStr);
1684 bp.gids = appendInt(bp.gids, gid);
1686 Slog.w(TAG, "<group> without gid at "
1687 + parser.getPositionDescription());
1690 XmlUtils.skipCurrentTag(parser);
1694 static int[] appendInts(int[] cur, int[] add) {
1695 if (add == null) return cur;
1696 if (cur == null) return add;
1697 final int N = add.length;
1698 for (int i=0; i<N; i++) {
1699 cur = appendInt(cur, add[i]);
1704 static int[] removeInts(int[] cur, int[] rem) {
1705 if (rem == null) return cur;
1706 if (cur == null) return cur;
1707 final int N = rem.length;
1708 for (int i=0; i<N; i++) {
1709 cur = removeInt(cur, rem[i]);
1714 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1715 if (!sUserManager.exists(userId)) return null;
1717 final PackageSetting ps = (PackageSetting) p.mExtras;
1721 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1722 final PackageUserState state = ps.readUserState(userId);
1723 return PackageParser.generatePackageInfo(p, gp.gids, flags,
1724 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1729 public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1730 if (!sUserManager.exists(userId)) return null;
1731 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
1733 synchronized (mPackages) {
1734 PackageParser.Package p = mPackages.get(packageName);
1735 if (DEBUG_PACKAGE_INFO)
1736 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1738 return generatePackageInfo(p, flags, userId);
1740 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1741 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1747 public String[] currentToCanonicalPackageNames(String[] names) {
1748 String[] out = new String[names.length];
1750 synchronized (mPackages) {
1751 for (int i=names.length-1; i>=0; i--) {
1752 PackageSetting ps = mSettings.mPackages.get(names[i]);
1753 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1759 public String[] canonicalToCurrentPackageNames(String[] names) {
1760 String[] out = new String[names.length];
1762 synchronized (mPackages) {
1763 for (int i=names.length-1; i>=0; i--) {
1764 String cur = mSettings.mRenamedPackages.get(names[i]);
1765 out[i] = cur != null ? cur : names[i];
1772 public int getPackageUid(String packageName, int userId) {
1773 if (!sUserManager.exists(userId)) return -1;
1774 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
1776 synchronized (mPackages) {
1777 PackageParser.Package p = mPackages.get(packageName);
1779 return UserHandle.getUid(userId, p.applicationInfo.uid);
1781 PackageSetting ps = mSettings.mPackages.get(packageName);
1782 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1786 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1790 public int[] getPackageGids(String packageName) {
1791 final boolean enforcedDefault = isPermissionEnforcedDefault(READ_EXTERNAL_STORAGE);
1793 synchronized (mPackages) {
1794 PackageParser.Package p = mPackages.get(packageName);
1795 if (DEBUG_PACKAGE_INFO)
1796 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1798 final PackageSetting ps = (PackageSetting)p.mExtras;
1799 final SharedUserSetting suid = ps.sharedUser;
1800 int[] gids = suid != null ? suid.gids : ps.gids;
1802 // include GIDs for any unenforced permissions
1803 if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE, enforcedDefault)) {
1804 final BasePermission basePerm = mSettings.mPermissions.get(
1805 READ_EXTERNAL_STORAGE);
1806 gids = appendInts(gids, basePerm.gids);
1812 // stupid thing to indicate an error.
1816 static final PermissionInfo generatePermissionInfo(
1817 BasePermission bp, int flags) {
1818 if (bp.perm != null) {
1819 return PackageParser.generatePermissionInfo(bp.perm, flags);
1821 PermissionInfo pi = new PermissionInfo();
1823 pi.packageName = bp.sourcePackage;
1824 pi.nonLocalizedLabel = bp.name;
1825 pi.protectionLevel = bp.protectionLevel;
1829 public PermissionInfo getPermissionInfo(String name, int flags) {
1831 synchronized (mPackages) {
1832 final BasePermission p = mSettings.mPermissions.get(name);
1834 return generatePermissionInfo(p, flags);
1840 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
1842 synchronized (mPackages) {
1843 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
1844 for (BasePermission p : mSettings.mPermissions.values()) {
1845 if (group == null) {
1846 if (p.perm == null || p.perm.info.group == null) {
1847 out.add(generatePermissionInfo(p, flags));
1850 if (p.perm != null && group.equals(p.perm.info.group)) {
1851 out.add(PackageParser.generatePermissionInfo(p.perm, flags));
1856 if (out.size() > 0) {
1859 return mPermissionGroups.containsKey(group) ? out : null;
1863 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
1865 synchronized (mPackages) {
1866 return PackageParser.generatePermissionGroupInfo(
1867 mPermissionGroups.get(name), flags);
1871 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1873 synchronized (mPackages) {
1874 final int N = mPermissionGroups.size();
1875 ArrayList<PermissionGroupInfo> out
1876 = new ArrayList<PermissionGroupInfo>(N);
1877 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
1878 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
1884 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
1886 if (!sUserManager.exists(userId)) return null;
1887 PackageSetting ps = mSettings.mPackages.get(packageName);
1889 if (ps.pkg == null) {
1890 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
1892 if (pInfo != null) {
1893 return pInfo.applicationInfo;
1897 return PackageParser.generateApplicationInfo(ps.pkg, flags,
1898 ps.readUserState(userId), userId);
1903 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
1905 if (!sUserManager.exists(userId)) return null;
1906 PackageSetting ps = mSettings.mPackages.get(packageName);
1908 PackageParser.Package pkg = ps.pkg;
1910 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
1913 pkg = new PackageParser.Package(packageName);
1914 pkg.applicationInfo.packageName = packageName;
1915 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
1916 pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
1917 pkg.applicationInfo.sourceDir = ps.codePathString;
1918 pkg.applicationInfo.dataDir =
1919 getDataPathForPackage(packageName, 0).getPath();
1920 pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
1922 // pkg.mSetEnabled = ps.getEnabled(userId);
1923 // pkg.mSetStopped = ps.getStopped(userId);
1924 return generatePackageInfo(pkg, flags, userId);
1930 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
1931 if (!sUserManager.exists(userId)) return null;
1932 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
1934 synchronized (mPackages) {
1935 PackageParser.Package p = mPackages.get(packageName);
1936 if (DEBUG_PACKAGE_INFO) Log.v(
1937 TAG, "getApplicationInfo " + packageName
1940 PackageSetting ps = mSettings.mPackages.get(packageName);
1941 if (ps == null) return null;
1942 // Note: isEnabledLP() does not apply here - always return info
1943 return PackageParser.generateApplicationInfo(
1944 p, flags, ps.readUserState(userId), userId);
1946 if ("android".equals(packageName)||"system".equals(packageName)) {
1947 return mAndroidApplication;
1949 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1950 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
1957 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
1958 mContext.enforceCallingOrSelfPermission(
1959 android.Manifest.permission.CLEAR_APP_CACHE, null);
1960 // Queue up an async operation since clearing cache may take a little while.
1961 mHandler.post(new Runnable() {
1963 mHandler.removeCallbacks(this);
1965 synchronized (mInstallLock) {
1966 retCode = mInstaller.freeCache(freeStorageSize);
1968 Slog.w(TAG, "Couldn't clear application caches");
1971 if (observer != null) {
1973 observer.onRemoveCompleted(null, (retCode >= 0));
1974 } catch (RemoteException e) {
1975 Slog.w(TAG, "RemoveException when invoking call back");
1982 public void freeStorage(final long freeStorageSize, final IntentSender pi) {
1983 mContext.enforceCallingOrSelfPermission(
1984 android.Manifest.permission.CLEAR_APP_CACHE, null);
1985 // Queue up an async operation since clearing cache may take a little while.
1986 mHandler.post(new Runnable() {
1988 mHandler.removeCallbacks(this);
1990 synchronized (mInstallLock) {
1991 retCode = mInstaller.freeCache(freeStorageSize);
1993 Slog.w(TAG, "Couldn't clear application caches");
1998 // Callback via pending intent
1999 int code = (retCode >= 0) ? 1 : 0;
2000 pi.sendIntent(null, code, null,
2002 } catch (SendIntentException e1) {
2003 Slog.i(TAG, "Failed to send pending intent");
2011 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2012 if (!sUserManager.exists(userId)) return null;
2013 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
2014 synchronized (mPackages) {
2015 PackageParser.Activity a = mActivities.mActivities.get(component);
2017 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2018 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2019 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2020 if (ps == null) return null;
2021 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2024 if (mResolveComponentName.equals(component)) {
2025 return mResolveActivity;
2032 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2033 if (!sUserManager.exists(userId)) return null;
2034 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
2035 synchronized (mPackages) {
2036 PackageParser.Activity a = mReceivers.mActivities.get(component);
2037 if (DEBUG_PACKAGE_INFO) Log.v(
2038 TAG, "getReceiverInfo " + component + ": " + a);
2039 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2040 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2041 if (ps == null) return null;
2042 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2050 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2051 if (!sUserManager.exists(userId)) return null;
2052 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
2053 synchronized (mPackages) {
2054 PackageParser.Service s = mServices.mServices.get(component);
2055 if (DEBUG_PACKAGE_INFO) Log.v(
2056 TAG, "getServiceInfo " + component + ": " + s);
2057 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2058 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2059 if (ps == null) return null;
2060 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2068 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2069 if (!sUserManager.exists(userId)) return null;
2070 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
2071 synchronized (mPackages) {
2072 PackageParser.Provider p = mProvidersByComponent.get(component);
2073 if (DEBUG_PACKAGE_INFO) Log.v(
2074 TAG, "getProviderInfo " + component + ": " + p);
2075 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2076 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2077 if (ps == null) return null;
2078 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2085 public String[] getSystemSharedLibraryNames() {
2087 synchronized (mPackages) {
2088 libSet = mSharedLibraries.keySet();
2089 int size = libSet.size();
2091 String[] libs = new String[size];
2092 libSet.toArray(libs);
2099 public FeatureInfo[] getSystemAvailableFeatures() {
2100 Collection<FeatureInfo> featSet;
2101 synchronized (mPackages) {
2102 featSet = mAvailableFeatures.values();
2103 int size = featSet.size();
2105 FeatureInfo[] features = new FeatureInfo[size+1];
2106 featSet.toArray(features);
2107 FeatureInfo fi = new FeatureInfo();
2108 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2109 FeatureInfo.GL_ES_VERSION_UNDEFINED);
2110 features[size] = fi;
2117 public boolean hasSystemFeature(String name) {
2118 synchronized (mPackages) {
2119 return mAvailableFeatures.containsKey(name);
2123 private void checkValidCaller(int uid, int userId) {
2124 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2127 throw new SecurityException("Caller uid=" + uid
2128 + " is not privileged to communicate with user=" + userId);
2131 public int checkPermission(String permName, String pkgName) {
2132 final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
2133 synchronized (mPackages) {
2134 PackageParser.Package p = mPackages.get(pkgName);
2135 if (p != null && p.mExtras != null) {
2136 PackageSetting ps = (PackageSetting)p.mExtras;
2137 if (ps.sharedUser != null) {
2138 if (ps.sharedUser.grantedPermissions.contains(permName)) {
2139 return PackageManager.PERMISSION_GRANTED;
2141 } else if (ps.grantedPermissions.contains(permName)) {
2142 return PackageManager.PERMISSION_GRANTED;
2145 if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
2146 return PackageManager.PERMISSION_GRANTED;
2149 return PackageManager.PERMISSION_DENIED;
2152 public int checkUidPermission(String permName, int uid) {
2153 final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
2154 synchronized (mPackages) {
2155 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2157 GrantedPermissions gp = (GrantedPermissions)obj;
2158 if (gp.grantedPermissions.contains(permName)) {
2159 return PackageManager.PERMISSION_GRANTED;
2162 HashSet<String> perms = mSystemPermissions.get(uid);
2163 if (perms != null && perms.contains(permName)) {
2164 return PackageManager.PERMISSION_GRANTED;
2167 if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
2168 return PackageManager.PERMISSION_GRANTED;
2171 return PackageManager.PERMISSION_DENIED;
2175 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2176 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2177 * @param message the message to log on security exception
2180 private void enforceCrossUserPermission(int callingUid, int userId,
2181 boolean requireFullPermission, String message) {
2183 throw new IllegalArgumentException("Invalid userId " + userId);
2185 if (userId == UserHandle.getUserId(callingUid)) return;
2186 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2187 if (requireFullPermission) {
2188 mContext.enforceCallingOrSelfPermission(
2189 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2192 mContext.enforceCallingOrSelfPermission(
2193 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2194 } catch (SecurityException se) {
2195 mContext.enforceCallingOrSelfPermission(
2196 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2202 private BasePermission findPermissionTreeLP(String permName) {
2203 for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2204 if (permName.startsWith(bp.name) &&
2205 permName.length() > bp.name.length() &&
2206 permName.charAt(bp.name.length()) == '.') {
2213 private BasePermission checkPermissionTreeLP(String permName) {
2214 if (permName != null) {
2215 BasePermission bp = findPermissionTreeLP(permName);
2217 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2220 throw new SecurityException("Calling uid "
2221 + Binder.getCallingUid()
2222 + " is not allowed to add to permission tree "
2223 + bp.name + " owned by uid " + bp.uid);
2226 throw new SecurityException("No permission tree found for " + permName);
2229 static boolean compareStrings(CharSequence s1, CharSequence s2) {
2236 if (s1.getClass() != s2.getClass()) {
2239 return s1.equals(s2);
2242 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2243 if (pi1.icon != pi2.icon) return false;
2244 if (pi1.logo != pi2.logo) return false;
2245 if (pi1.protectionLevel != pi2.protectionLevel) return false;
2246 if (!compareStrings(pi1.name, pi2.name)) return false;
2247 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2248 // We'll take care of setting this one.
2249 if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2250 // These are not currently stored in settings.
2251 //if (!compareStrings(pi1.group, pi2.group)) return false;
2252 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2253 //if (pi1.labelRes != pi2.labelRes) return false;
2254 //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2258 boolean addPermissionLocked(PermissionInfo info, boolean async) {
2259 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2260 throw new SecurityException("Label must be specified in permission");
2262 BasePermission tree = checkPermissionTreeLP(info.name);
2263 BasePermission bp = mSettings.mPermissions.get(info.name);
2264 boolean added = bp == null;
2265 boolean changed = true;
2266 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2268 bp = new BasePermission(info.name, tree.sourcePackage,
2269 BasePermission.TYPE_DYNAMIC);
2270 } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2271 throw new SecurityException(
2272 "Not allowed to modify non-dynamic permission "
2275 if (bp.protectionLevel == fixedLevel
2276 && bp.perm.owner.equals(tree.perm.owner)
2277 && bp.uid == tree.uid
2278 && comparePermissionInfos(bp.perm.info, info)) {
2282 bp.protectionLevel = fixedLevel;
2283 info = new PermissionInfo(info);
2284 info.protectionLevel = fixedLevel;
2285 bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2286 bp.perm.info.packageName = tree.perm.info.packageName;
2289 mSettings.mPermissions.put(info.name, bp);
2293 mSettings.writeLPr();
2295 scheduleWriteSettingsLocked();
2301 public boolean addPermission(PermissionInfo info) {
2302 synchronized (mPackages) {
2303 return addPermissionLocked(info, false);
2307 public boolean addPermissionAsync(PermissionInfo info) {
2308 synchronized (mPackages) {
2309 return addPermissionLocked(info, true);
2313 public void removePermission(String name) {
2314 synchronized (mPackages) {
2315 checkPermissionTreeLP(name);
2316 BasePermission bp = mSettings.mPermissions.get(name);
2318 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2319 throw new SecurityException(
2320 "Not allowed to modify non-dynamic permission "
2323 mSettings.mPermissions.remove(name);
2324 mSettings.writeLPr();
2329 private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2330 int index = pkg.requestedPermissions.indexOf(bp.name);
2332 throw new SecurityException("Package " + pkg.packageName
2333 + " has not requested permission " + bp.name);
2336 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2337 == PermissionInfo.PROTECTION_NORMAL);
2338 boolean isDangerous =
2339 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2340 == PermissionInfo.PROTECTION_DANGEROUS);
2341 boolean isDevelopment =
2342 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2344 if (!isNormal && !isDangerous && !isDevelopment) {
2345 throw new SecurityException("Permission " + bp.name
2346 + " is not a changeable permission type");
2349 if (isNormal || isDangerous) {
2350 if (pkg.requestedPermissionsRequired.get(index)) {
2351 throw new SecurityException("Can't change " + bp.name
2352 + ". It is required by the application");
2357 public void grantPermission(String packageName, String permissionName) {
2358 mContext.enforceCallingOrSelfPermission(
2359 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2360 synchronized (mPackages) {
2361 final PackageParser.Package pkg = mPackages.get(packageName);
2363 throw new IllegalArgumentException("Unknown package: " + packageName);
2365 final BasePermission bp = mSettings.mPermissions.get(permissionName);
2367 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2370 checkGrantRevokePermissions(pkg, bp);
2372 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2376 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2377 if (gp.grantedPermissions.add(permissionName)) {
2379 gp.gids = appendInts(gp.gids, bp.gids);
2381 mSettings.writeLPr();
2386 public void revokePermission(String packageName, String permissionName) {
2387 int changedAppId = -1;
2389 synchronized (mPackages) {
2390 final PackageParser.Package pkg = mPackages.get(packageName);
2392 throw new IllegalArgumentException("Unknown package: " + packageName);
2394 if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2395 mContext.enforceCallingOrSelfPermission(
2396 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2398 final BasePermission bp = mSettings.mPermissions.get(permissionName);
2400 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2403 checkGrantRevokePermissions(pkg, bp);
2405 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2409 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2410 if (gp.grantedPermissions.remove(permissionName)) {
2411 gp.grantedPermissions.remove(permissionName);
2413 gp.gids = removeInts(gp.gids, bp.gids);
2415 mSettings.writeLPr();
2416 changedAppId = ps.appId;
2420 if (changedAppId >= 0) {
2421 // We changed the perm on someone, kill its processes.
2422 IActivityManager am = ActivityManagerNative.getDefault();
2424 final int callingUserId = UserHandle.getCallingUserId();
2425 final long ident = Binder.clearCallingIdentity();
2427 //XXX we should only revoke for the calling user's app permissions,
2428 // but for now we impact all users.
2429 //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2430 // "revoke " + permissionName);
2431 int[] users = sUserManager.getUserIds();
2432 for (int user : users) {
2433 am.killUid(UserHandle.getUid(user, changedAppId),
2434 "revoke " + permissionName);
2436 } catch (RemoteException e) {
2438 Binder.restoreCallingIdentity(ident);
2444 public boolean isProtectedBroadcast(String actionName) {
2445 synchronized (mPackages) {
2446 return mProtectedBroadcasts.contains(actionName);
2450 public int checkSignatures(String pkg1, String pkg2) {
2451 synchronized (mPackages) {
2452 final PackageParser.Package p1 = mPackages.get(pkg1);
2453 final PackageParser.Package p2 = mPackages.get(pkg2);
2454 if (p1 == null || p1.mExtras == null
2455 || p2 == null || p2.mExtras == null) {
2456 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2458 return compareSignatures(p1.mSignatures, p2.mSignatures);
2462 public int checkUidSignatures(int uid1, int uid2) {
2463 // Map to base uids.
2464 uid1 = UserHandle.getAppId(uid1);
2465 uid2 = UserHandle.getAppId(uid2);
2467 synchronized (mPackages) {
2470 Object obj = mSettings.getUserIdLPr(uid1);
2472 if (obj instanceof SharedUserSetting) {
2473 s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2474 } else if (obj instanceof PackageSetting) {
2475 s1 = ((PackageSetting)obj).signatures.mSignatures;
2477 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2480 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2482 obj = mSettings.getUserIdLPr(uid2);
2484 if (obj instanceof SharedUserSetting) {
2485 s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2486 } else if (obj instanceof PackageSetting) {
2487 s2 = ((PackageSetting)obj).signatures.mSignatures;
2489 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2492 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2494 return compareSignatures(s1, s2);
2498 static int compareSignatures(Signature[] s1, Signature[] s2) {
2501 ? PackageManager.SIGNATURE_NEITHER_SIGNED
2502 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2505 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2507 HashSet<Signature> set1 = new HashSet<Signature>();
2508 for (Signature sig : s1) {
2511 HashSet<Signature> set2 = new HashSet<Signature>();
2512 for (Signature sig : s2) {
2515 // Make sure s2 contains all signatures in s1.
2516 if (set1.equals(set2)) {
2517 return PackageManager.SIGNATURE_MATCH;
2519 return PackageManager.SIGNATURE_NO_MATCH;
2522 public String[] getPackagesForUid(int uid) {
2523 uid = UserHandle.getAppId(uid);
2525 synchronized (mPackages) {
2526 Object obj = mSettings.getUserIdLPr(uid);
2527 if (obj instanceof SharedUserSetting) {
2528 final SharedUserSetting sus = (SharedUserSetting) obj;
2529 final int N = sus.packages.size();
2530 final String[] res = new String[N];
2531 final Iterator<PackageSetting> it = sus.packages.iterator();
2533 while (it.hasNext()) {
2534 res[i++] = it.next().name;
2537 } else if (obj instanceof PackageSetting) {
2538 final PackageSetting ps = (PackageSetting) obj;
2539 return new String[] { ps.name };
2545 public String getNameForUid(int uid) {
2547 synchronized (mPackages) {
2548 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2549 if (obj instanceof SharedUserSetting) {
2550 final SharedUserSetting sus = (SharedUserSetting) obj;
2551 return sus.name + ":" + sus.userId;
2552 } else if (obj instanceof PackageSetting) {
2553 final PackageSetting ps = (PackageSetting) obj;
2560 public int getUidForSharedUser(String sharedUserName) {
2561 if(sharedUserName == null) {
2565 synchronized (mPackages) {
2566 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2575 public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2576 int flags, int userId) {
2577 if (!sUserManager.exists(userId)) return null;
2578 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
2579 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2580 return chooseBestActivity(intent, resolvedType, flags, query, userId);
2583 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
2584 int flags, List<ResolveInfo> query, int userId) {
2585 if (query != null) {
2586 final int N = query.size();
2588 return query.get(0);
2590 // If there is more than one activity with the same priority,
2591 // then let the user decide between them.
2592 ResolveInfo r0 = query.get(0);
2593 ResolveInfo r1 = query.get(1);
2594 if (DEBUG_INTENT_MATCHING) {
2595 Log.d(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
2596 + r1.activityInfo.name + "=" + r1.priority);
2598 // If the first activity has a higher priority, or a different
2599 // default, then it is always desireable to pick it.
2600 if (r0.priority != r1.priority
2601 || r0.preferredOrder != r1.preferredOrder
2602 || r0.isDefault != r1.isDefault) {
2603 return query.get(0);
2605 // If we have saved a preference for a preferred activity for
2606 // this Intent, use that.
2607 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
2608 flags, query, r0.priority, userId);
2613 ri = new ResolveInfo(mResolveInfo);
2614 ri.activityInfo = new ActivityInfo(ri.activityInfo);
2615 ri.activityInfo.applicationInfo = new ApplicationInfo(
2616 ri.activityInfo.applicationInfo);
2617 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
2618 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
2621 return mResolveInfo;
2627 ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
2628 int flags, List<ResolveInfo> query, int priority, int userId) {
2629 if (!sUserManager.exists(userId)) return null;
2631 synchronized (mPackages) {
2632 if (intent.getSelector() != null) {
2633 intent = intent.getSelector();
2635 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
2636 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
2637 List<PreferredActivity> prefs = pir != null
2638 ? pir.queryIntent(intent, resolvedType,
2639 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
2641 if (prefs != null && prefs.size() > 0) {
2642 // First figure out how good the original match set is.
2643 // We will only allow preferred activities that came
2644 // from the same match quality.
2647 if (DEBUG_PREFERRED) {
2648 Log.v(TAG, "Figuring out best match...");
2651 final int N = query.size();
2652 for (int j=0; j<N; j++) {
2653 final ResolveInfo ri = query.get(j);
2654 if (DEBUG_PREFERRED) {
2655 Log.v(TAG, "Match for " + ri.activityInfo + ": 0x"
2656 + Integer.toHexString(match));
2658 if (ri.match > match) {
2663 if (DEBUG_PREFERRED) {
2664 Log.v(TAG, "Best match: 0x" + Integer.toHexString(match));
2667 match &= IntentFilter.MATCH_CATEGORY_MASK;
2668 final int M = prefs.size();
2669 for (int i=0; i<M; i++) {
2670 final PreferredActivity pa = prefs.get(i);
2671 if (pa.mPref.mMatch != match) {
2674 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
2675 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
2676 if (DEBUG_PREFERRED) {
2677 Log.v(TAG, "Got preferred activity:");
2679 ai.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
2681 Log.v(TAG, " null");
2685 // This previously registered preferred activity
2686 // component is no longer known. Most likely an update
2687 // to the app was installed and in the new version this
2688 // component no longer exists. Clean it up by removing
2689 // it from the preferred activities list, and skip it.
2690 Slog.w(TAG, "Removing dangling preferred activity: "
2691 + pa.mPref.mComponent);
2692 pir.removeFilter(pa);
2695 for (int j=0; j<N; j++) {
2696 final ResolveInfo ri = query.get(j);
2697 if (!ri.activityInfo.applicationInfo.packageName
2698 .equals(ai.applicationInfo.packageName)) {
2701 if (!ri.activityInfo.name.equals(ai.name)) {
2705 // Okay we found a previously set preferred app.
2706 // If the result set is different from when this
2707 // was created, we need to clear it and re-ask the
2708 // user their preference.
2709 if (!pa.mPref.sameSet(query, priority)) {
2710 Slog.i(TAG, "Result set changed, dropping preferred activity for "
2711 + intent + " type " + resolvedType);
2712 pir.removeFilter(pa);
2726 public List<ResolveInfo> queryIntentActivities(Intent intent,
2727 String resolvedType, int flags, int userId) {
2728 if (!sUserManager.exists(userId)) return Collections.emptyList();
2729 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
2730 ComponentName comp = intent.getComponent();
2732 if (intent.getSelector() != null) {
2733 intent = intent.getSelector();
2734 comp = intent.getComponent();
2739 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2740 final ActivityInfo ai = getActivityInfo(comp, flags, userId);
2742 final ResolveInfo ri = new ResolveInfo();
2743 ri.activityInfo = ai;
2750 synchronized (mPackages) {
2751 final String pkgName = intent.getPackage();
2752 if (pkgName == null) {
2753 return mActivities.queryIntent(intent, resolvedType, flags, userId);
2755 final PackageParser.Package pkg = mPackages.get(pkgName);
2757 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
2758 pkg.activities, userId);
2760 return new ArrayList<ResolveInfo>();
2765 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
2766 Intent[] specifics, String[] specificTypes, Intent intent,
2767 String resolvedType, int flags, int userId) {
2768 if (!sUserManager.exists(userId)) return Collections.emptyList();
2769 enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
2770 "query intent activity options");
2771 final String resultsAction = intent.getAction();
2773 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
2774 | PackageManager.GET_RESOLVED_FILTER, userId);
2776 if (DEBUG_INTENT_MATCHING) {
2777 Log.v(TAG, "Query " + intent + ": " + results);
2780 int specificsPos = 0;
2783 // todo: note that the algorithm used here is O(N^2). This
2784 // isn't a problem in our current environment, but if we start running
2785 // into situations where we have more than 5 or 10 matches then this
2786 // should probably be changed to something smarter...
2788 // First we go through and resolve each of the specific items
2789 // that were supplied, taking care of removing any corresponding
2790 // duplicate items in the generic resolve list.
2791 if (specifics != null) {
2792 for (int i=0; i<specifics.length; i++) {
2793 final Intent sintent = specifics[i];
2794 if (sintent == null) {
2798 if (DEBUG_INTENT_MATCHING) {
2799 Log.v(TAG, "Specific #" + i + ": " + sintent);
2802 String action = sintent.getAction();
2803 if (resultsAction != null && resultsAction.equals(action)) {
2804 // If this action was explicitly requested, then don't
2805 // remove things that have it.
2809 ResolveInfo ri = null;
2810 ActivityInfo ai = null;
2812 ComponentName comp = sintent.getComponent();
2816 specificTypes != null ? specificTypes[i] : null,
2821 if (ri == mResolveInfo) {
2822 // ACK! Must do something better with this.
2824 ai = ri.activityInfo;
2825 comp = new ComponentName(ai.applicationInfo.packageName,
2828 ai = getActivityInfo(comp, flags, userId);
2834 // Look for any generic query activities that are duplicates
2835 // of this specific one, and remove them from the results.
2836 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
2839 for (j=specificsPos; j<N; j++) {
2840 ResolveInfo sri = results.get(j);
2841 if ((sri.activityInfo.name.equals(comp.getClassName())
2842 && sri.activityInfo.applicationInfo.packageName.equals(
2843 comp.getPackageName()))
2844 || (action != null && sri.filter.matchAction(action))) {
2846 if (DEBUG_INTENT_MATCHING) Log.v(
2847 TAG, "Removing duplicate item from " + j
2848 + " due to specific " + specificsPos);
2857 // Add this specific item to its proper place.
2859 ri = new ResolveInfo();
2860 ri.activityInfo = ai;
2862 results.add(specificsPos, ri);
2863 ri.specificIndex = i;
2868 // Now we go through the remaining generic results and remove any
2869 // duplicate actions that are found here.
2871 for (int i=specificsPos; i<N-1; i++) {
2872 final ResolveInfo rii = results.get(i);
2873 if (rii.filter == null) {
2877 // Iterate over all of the actions of this result's intent
2878 // filter... typically this should be just one.
2879 final Iterator<String> it = rii.filter.actionsIterator();
2883 while (it.hasNext()) {
2884 final String action = it.next();
2885 if (resultsAction != null && resultsAction.equals(action)) {
2886 // If this action was explicitly requested, then don't
2887 // remove things that have it.
2890 for (int j=i+1; j<N; j++) {
2891 final ResolveInfo rij = results.get(j);
2892 if (rij.filter != null && rij.filter.hasAction(action)) {
2894 if (DEBUG_INTENT_MATCHING) Log.v(
2895 TAG, "Removing duplicate item from " + j
2896 + " due to action " + action + " at " + i);
2903 // If the caller didn't request filter information, drop it now
2904 // so we don't have to marshall/unmarshall it.
2905 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2910 // Filter out the caller activity if so requested.
2911 if (caller != null) {
2913 for (int i=0; i<N; i++) {
2914 ActivityInfo ainfo = results.get(i).activityInfo;
2915 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
2916 && caller.getClassName().equals(ainfo.name)) {
2923 // If the caller didn't request filter information,
2924 // drop them now so we don't have to
2925 // marshall/unmarshall it.
2926 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2928 for (int i=0; i<N; i++) {
2929 results.get(i).filter = null;
2933 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
2938 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
2940 if (!sUserManager.exists(userId)) return Collections.emptyList();
2941 ComponentName comp = intent.getComponent();
2943 if (intent.getSelector() != null) {
2944 intent = intent.getSelector();
2945 comp = intent.getComponent();
2949 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2950 ActivityInfo ai = getReceiverInfo(comp, flags, userId);
2952 ResolveInfo ri = new ResolveInfo();
2953 ri.activityInfo = ai;
2960 synchronized (mPackages) {
2961 String pkgName = intent.getPackage();
2962 if (pkgName == null) {
2963 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
2965 final PackageParser.Package pkg = mPackages.get(pkgName);
2967 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
2975 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
2976 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
2977 if (!sUserManager.exists(userId)) return null;
2978 if (query != null) {
2979 if (query.size() >= 1) {
2980 // If there is more than one service with the same priority,
2981 // just arbitrarily pick the first one.
2982 return query.get(0);
2989 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
2991 if (!sUserManager.exists(userId)) return Collections.emptyList();
2992 ComponentName comp = intent.getComponent();
2994 if (intent.getSelector() != null) {
2995 intent = intent.getSelector();
2996 comp = intent.getComponent();
3000 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3001 final ServiceInfo si = getServiceInfo(comp, flags, userId);
3003 final ResolveInfo ri = new ResolveInfo();
3004 ri.serviceInfo = si;
3011 synchronized (mPackages) {
3012 String pkgName = intent.getPackage();
3013 if (pkgName == null) {
3014 return mServices.queryIntent(intent, resolvedType, flags, userId);
3016 final PackageParser.Package pkg = mPackages.get(pkgName);
3018 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3026 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3027 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3029 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
3032 synchronized (mPackages) {
3033 ArrayList<PackageInfo> list;
3034 if (listUninstalled) {
3035 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3036 for (PackageSetting ps : mSettings.mPackages.values()) {
3038 if (ps.pkg != null) {
3039 pi = generatePackageInfo(ps.pkg, flags, userId);
3041 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3048 list = new ArrayList<PackageInfo>(mPackages.size());
3049 for (PackageParser.Package p : mPackages.values()) {
3050 PackageInfo pi = generatePackageInfo(p, flags, userId);
3057 return new ParceledListSlice<PackageInfo>(list);
3061 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3062 String[] permissions, boolean[] tmp, int flags, int userId) {
3064 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3065 for (int i=0; i<permissions.length; i++) {
3066 if (gp.grantedPermissions.contains(permissions[i])) {
3073 if (numMatch == 0) {
3077 if (ps.pkg != null) {
3078 pi = generatePackageInfo(ps.pkg, flags, userId);
3080 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3082 if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3083 if (numMatch == permissions.length) {
3084 pi.requestedPermissions = permissions;
3086 pi.requestedPermissions = new String[numMatch];
3088 for (int i=0; i<permissions.length; i++) {
3090 pi.requestedPermissions[numMatch] = permissions[i];
3100 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3101 String[] permissions, int flags, int userId) {
3102 if (!sUserManager.exists(userId)) return null;
3103 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3106 synchronized (mPackages) {
3107 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3108 boolean[] tmpBools = new boolean[permissions.length];
3109 if (listUninstalled) {
3110 for (PackageSetting ps : mSettings.mPackages.values()) {
3111 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3114 for (PackageParser.Package pkg : mPackages.values()) {
3115 PackageSetting ps = (PackageSetting)pkg.mExtras;
3117 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3123 return new ParceledListSlice<PackageInfo>(list);
3128 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3129 if (!sUserManager.exists(userId)) return null;
3130 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3133 synchronized (mPackages) {
3134 ArrayList<ApplicationInfo> list;
3135 if (listUninstalled) {
3136 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3137 for (PackageSetting ps : mSettings.mPackages.values()) {
3139 if (ps.pkg != null) {
3140 ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3141 ps.readUserState(userId), userId);
3143 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3150 list = new ArrayList<ApplicationInfo>(mPackages.size());
3151 for (PackageParser.Package p : mPackages.values()) {
3152 if (p.mExtras != null) {
3153 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3154 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3162 return new ParceledListSlice<ApplicationInfo>(list);
3166 public List<ApplicationInfo> getPersistentApplications(int flags) {
3167 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3170 synchronized (mPackages) {
3171 final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3172 final int userId = UserHandle.getCallingUserId();
3173 while (i.hasNext()) {
3174 final PackageParser.Package p = i.next();
3175 if (p.applicationInfo != null
3176 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3177 && (!mSafeMode || isSystemApp(p))) {
3178 PackageSetting ps = mSettings.mPackages.get(p.packageName);
3180 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3181 ps.readUserState(userId), userId);
3194 public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3195 if (!sUserManager.exists(userId)) return null;
3197 synchronized (mPackages) {
3198 final PackageParser.Provider provider = mProviders.get(name);
3199 PackageSetting ps = provider != null
3200 ? mSettings.mPackages.get(provider.owner.packageName)
3203 && mSettings.isEnabledLPr(provider.info, flags, userId)
3204 && (!mSafeMode || (provider.info.applicationInfo.flags
3205 &ApplicationInfo.FLAG_SYSTEM) != 0)
3206 ? PackageParser.generateProviderInfo(provider, flags,
3207 ps.readUserState(userId), userId)
3216 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3218 synchronized (mPackages) {
3219 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
3221 final int userId = UserHandle.getCallingUserId();
3222 while (i.hasNext()) {
3223 Map.Entry<String, PackageParser.Provider> entry = i.next();
3224 PackageParser.Provider p = entry.getValue();
3225 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3227 if (ps != null && p.syncable
3228 && (!mSafeMode || (p.info.applicationInfo.flags
3229 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3230 ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3231 ps.readUserState(userId), userId);
3233 outNames.add(entry.getKey());
3241 public List<ProviderInfo> queryContentProviders(String processName,
3242 int uid, int flags) {
3243 ArrayList<ProviderInfo> finalList = null;
3246 synchronized (mPackages) {
3247 final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
3248 final int userId = processName != null ?
3249 UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3250 while (i.hasNext()) {
3251 final PackageParser.Provider p = i.next();
3252 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3253 if (ps != null && p.info.authority != null
3254 && (processName == null
3255 || (p.info.processName.equals(processName)
3256 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3257 && mSettings.isEnabledLPr(p.info, flags, userId)
3259 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3260 if (finalList == null) {
3261 finalList = new ArrayList<ProviderInfo>(3);
3263 ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3264 ps.readUserState(userId), userId);
3266 finalList.add(info);
3272 if (finalList != null) {
3273 Collections.sort(finalList, mProviderInitOrderSorter);
3279 public InstrumentationInfo getInstrumentationInfo(ComponentName name,
3282 synchronized (mPackages) {
3283 final PackageParser.Instrumentation i = mInstrumentation.get(name);
3284 return PackageParser.generateInstrumentationInfo(i, flags);
3288 public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
3290 ArrayList<InstrumentationInfo> finalList =
3291 new ArrayList<InstrumentationInfo>();
3294 synchronized (mPackages) {
3295 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
3296 while (i.hasNext()) {
3297 final PackageParser.Instrumentation p = i.next();
3298 if (targetPackage == null
3299 || targetPackage.equals(p.info.targetPackage)) {
3300 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
3312 private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
3313 String[] files = dir.list();
3314 if (files == null) {
3315 Log.d(TAG, "No files in app dir " + dir);
3319 if (DEBUG_PACKAGE_SCANNING) {
3320 Log.d(TAG, "Scanning app dir " + dir);
3324 for (i=0; i<files.length; i++) {
3325 File file = new File(dir, files[i]);
3326 if (!isPackageFilename(files[i])) {
3327 // Ignore entries which are not apk's
3330 PackageParser.Package pkg = scanPackageLI(file,
3331 flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
3332 // Don't mess around with apps in system partition.
3333 if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
3334 mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
3336 Slog.w(TAG, "Cleaning up failed install of " + file);
3342 private static File getSettingsProblemFile() {
3343 File dataDir = Environment.getDataDirectory();
3344 File systemDir = new File(dataDir, "system");
3345 File fname = new File(systemDir, "uiderrors.txt");
3349 static void reportSettingsProblem(int priority, String msg) {
3351 File fname = getSettingsProblemFile();
3352 FileOutputStream out = new FileOutputStream(fname, true);
3353 PrintWriter pw = new PrintWriter(out);
3354 SimpleDateFormat formatter = new SimpleDateFormat();
3355 String dateString = formatter.format(new Date(System.currentTimeMillis()));
3356 pw.println(dateString + ": " + msg);
3358 FileUtils.setPermissions(
3360 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
3362 } catch (java.io.IOException e) {
3364 Slog.println(priority, TAG, msg);
3367 private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
3368 PackageParser.Package pkg, File srcFile, int parseFlags) {
3369 if (GET_CERTIFICATES) {
3371 && ps.codePath.equals(srcFile)
3372 && ps.timeStamp == srcFile.lastModified()) {
3373 if (ps.signatures.mSignatures != null
3374 && ps.signatures.mSignatures.length != 0) {
3375 // Optimization: reuse the existing cached certificates
3376 // if the package appears to be unchanged.
3377 pkg.mSignatures = ps.signatures.mSignatures;
3381 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them.");
3383 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
3386 if (!pp.collectCertificates(pkg, parseFlags)) {
3387 mLastScanError = pp.getParseError();
3395 * Scan a package and return the newly parsed package.
3396 * Returns null in case of errors and the error code is stored in mLastScanError
3398 private PackageParser.Package scanPackageLI(File scanFile,
3399 int parseFlags, int scanMode, long currentTime, UserHandle user) {
3400 mLastScanError = PackageManager.INSTALL_SUCCEEDED;
3401 String scanPath = scanFile.getPath();
3402 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath);
3403 parseFlags |= mDefParseFlags;
3404 PackageParser pp = new PackageParser(scanPath);
3405 pp.setSeparateProcesses(mSeparateProcesses);
3406 pp.setOnlyCoreApps(mOnlyCore);
3407 final PackageParser.Package pkg = pp.parsePackage(scanFile,
3408 scanPath, mMetrics, parseFlags);
3410 mLastScanError = pp.getParseError();
3413 PackageSetting ps = null;
3414 PackageSetting updatedPkg;
3416 synchronized (mPackages) {
3417 // Look to see if we already know about this package.
3418 String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
3419 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
3420 // This package has been renamed to its original name. Let's
3422 ps = mSettings.peekPackageLPr(oldName);
3424 // If there was no original package, see one for the real package name.
3426 ps = mSettings.peekPackageLPr(pkg.packageName);
3428 // Check to see if this package could be hiding/updating a system
3429 // package. Must look for it either under the original or real
3430 // package name depending on our state.
3431 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
3432 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
3434 // First check if this is a system package that may involve an update
3435 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
3436 if (ps != null && !ps.codePath.equals(scanFile)) {
3437 // The path has changed from what was last scanned... check the
3438 // version of the new path against what we have stored to determine
3440 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
3441 if (pkg.mVersionCode < ps.versionCode) {
3442 // The system package has been updated and the code path does not match
3443 // Ignore entry. Skip it.
3444 Log.i(TAG, "Package " + ps.name + " at " + scanFile
3445 + " ignored: updated version " + ps.versionCode
3446 + " better than this " + pkg.mVersionCode);
3447 if (!updatedPkg.codePath.equals(scanFile)) {
3448 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
3449 + ps.name + " changing from " + updatedPkg.codePathString
3450 + " to " + scanFile);
3451 updatedPkg.codePath = scanFile;
3452 updatedPkg.codePathString = scanFile.toString();
3454 updatedPkg.pkg = pkg;
3455 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3458 // The current app on the system partion is better than
3459 // what we have updated to on the data partition; switch
3460 // back to the system partition version.
3461 // At this point, its safely assumed that package installation for
3462 // apps in system partition will go through. If not there won't be a working
3463 // version of the app
3465 synchronized (mPackages) {
3466 // Just remove the loaded entries from package lists.
3467 mPackages.remove(ps.name);
3469 Slog.w(TAG, "Package " + ps.name + " at " + scanFile
3470 + "reverting from " + ps.codePathString
3471 + ": new version " + pkg.mVersionCode
3472 + " better than installed " + ps.versionCode);
3474 InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3475 ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3476 synchronized (mInstallLock) {
3477 args.cleanUpResourcesLI();
3479 synchronized (mPackages) {
3480 mSettings.enableSystemPackageLPw(ps.name);
3486 if (updatedPkg != null) {
3487 // An updated system app will not have the PARSE_IS_SYSTEM flag set
3489 parseFlags |= PackageParser.PARSE_IS_SYSTEM;
3491 // Verify certificates against what was last scanned
3492 if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
3493 Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
3498 * A new system app appeared, but we already had a non-system one of the
3499 * same name installed earlier.
3501 boolean shouldHideSystemApp = false;
3502 if (updatedPkg == null && ps != null
3503 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
3505 * Check to make sure the signatures match first. If they don't,
3506 * wipe the installed application and its data.
3508 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
3509 != PackageManager.SIGNATURE_MATCH) {
3510 if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!");
3511 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
3515 * If the newly-added system app is an older version than the
3516 * already installed version, hide it. It will be scanned later
3517 * and re-added like an update.
3519 if (pkg.mVersionCode < ps.versionCode) {
3520 shouldHideSystemApp = true;
3523 * The newly found system app is a newer version that the
3524 * one previously installed. Simply remove the
3525 * already-installed application and replace it with our own
3526 * while keeping the application data.
3528 Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
3529 + ps.codePathString + ": new version " + pkg.mVersionCode
3530 + " better than installed " + ps.versionCode);
3531 InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3532 ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3533 synchronized (mInstallLock) {
3534 args.cleanUpResourcesLI();
3540 // The apk is forward locked (not public) if its code and resources
3541 // are kept in different files.
3542 // TODO grab this value from PackageSettings
3543 if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
3544 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
3547 String codePath = null;
3548 String resPath = null;
3549 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
3550 if (ps != null && ps.resourcePathString != null) {
3551 resPath = ps.resourcePathString;
3553 // Should not happen at all. Just log an error.
3554 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
3557 resPath = pkg.mScanPath;
3559 codePath = pkg.mScanPath;
3560 // Set application objects path explicitly.
3561 setApplicationInfoPaths(pkg, codePath, resPath);
3562 // Note that we invoke the following method only if we are about to unpack an application
3563 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
3564 | SCAN_UPDATE_SIGNATURE, currentTime, user);
3567 * If the system app should be overridden by a previously installed
3568 * data, hide the system app now and let the /data/app scan pick it up
3571 if (shouldHideSystemApp) {
3572 synchronized (mPackages) {
3574 * We have to grant systems permissions before we hide, because
3575 * grantPermissions will assume the package update is trying to
3576 * expand its permissions.
3578 grantPermissionsLPw(pkg, true);
3579 mSettings.disableSystemPackageLPw(pkg.packageName);
3586 private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
3587 String destResPath) {
3588 pkg.mPath = pkg.mScanPath = destCodePath;
3589 pkg.applicationInfo.sourceDir = destCodePath;
3590 pkg.applicationInfo.publicSourceDir = destResPath;
3593 private static String fixProcessName(String defProcessName,
3594 String processName, int uid) {
3595 if (processName == null) {
3596 return defProcessName;
3601 private boolean verifySignaturesLP(PackageSetting pkgSetting,
3602 PackageParser.Package pkg) {
3603 if (pkgSetting.signatures.mSignatures != null) {
3604 // Already existing package. Make sure signatures match
3605 if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
3606 PackageManager.SIGNATURE_MATCH) {
3607 Slog.e(TAG, "Package " + pkg.packageName
3608 + " signatures do not match the previously installed version; ignoring!");
3609 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3613 // Check for shared user signatures
3614 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
3615 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
3616 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
3617 Slog.e(TAG, "Package " + pkg.packageName
3618 + " has no signatures that match those in shared user "
3619 + pkgSetting.sharedUser.name + "; ignoring!");
3620 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3628 * Enforces that only the system UID or root's UID can call a method exposed
3631 * @param message used as message if SecurityException is thrown
3632 * @throws SecurityException if the caller is not system or root
3634 private static final void enforceSystemOrRoot(String message) {
3635 final int uid = Binder.getCallingUid();
3636 if (uid != Process.SYSTEM_UID && uid != 0) {
3637 throw new SecurityException(message);
3641 public void performBootDexOpt() {
3642 HashSet<PackageParser.Package> pkgs = null;
3643 synchronized (mPackages) {
3644 pkgs = mDeferredDexOpt;
3645 mDeferredDexOpt = null;
3649 for (PackageParser.Package pkg : pkgs) {
3650 if (!isFirstBoot()) {
3653 ActivityManagerNative.getDefault().showBootMessage(
3654 mContext.getResources().getString(
3655 com.android.internal.R.string.android_upgrading_apk,
3656 i, pkgs.size()), true);
3657 } catch (RemoteException e) {
3660 PackageParser.Package p = pkg;
3661 synchronized (mInstallLock) {
3662 if (!p.mDidDexOpt) {
3663 performDexOptLI(p, false, false, true);
3670 public boolean performDexOpt(String packageName) {
3671 enforceSystemOrRoot("Only the system can request dexopt be performed");
3677 PackageParser.Package p;
3678 synchronized (mPackages) {
3679 p = mPackages.get(packageName);
3680 if (p == null || p.mDidDexOpt) {
3684 synchronized (mInstallLock) {
3685 return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED;
3689 private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer,
3690 HashSet<String> done) {
3691 for (int i=0; i<libs.size(); i++) {
3692 PackageParser.Package libPkg;
3694 synchronized (mPackages) {
3695 libName = libs.get(i);
3696 SharedLibraryEntry lib = mSharedLibraries.get(libName);
3697 if (lib != null && lib.apk != null) {
3698 libPkg = mPackages.get(lib.apk);
3703 if (libPkg != null && !done.contains(libName)) {
3704 performDexOptLI(libPkg, forceDex, defer, done);
3709 static final int DEX_OPT_SKIPPED = 0;
3710 static final int DEX_OPT_PERFORMED = 1;
3711 static final int DEX_OPT_DEFERRED = 2;
3712 static final int DEX_OPT_FAILED = -1;
3714 private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
3715 HashSet<String> done) {
3716 boolean performed = false;
3718 done.add(pkg.packageName);
3719 if (pkg.usesLibraries != null) {
3720 performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done);
3722 if (pkg.usesOptionalLibraries != null) {
3723 performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done);
3726 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
3727 String path = pkg.mScanPath;
3730 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
3731 if (!forceDex && defer) {
3732 if (mDeferredDexOpt == null) {
3733 mDeferredDexOpt = new HashSet<PackageParser.Package>();
3735 mDeferredDexOpt.add(pkg);
3736 return DEX_OPT_DEFERRED;
3738 Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
3739 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
3740 ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg));
3741 pkg.mDidDexOpt = true;
3745 } catch (FileNotFoundException e) {
3746 Slog.w(TAG, "Apk not found for dexopt: " + path);
3748 } catch (IOException e) {
3749 Slog.w(TAG, "IOException reading apk: " + path, e);
3751 } catch (dalvik.system.StaleDexCacheError e) {
3752 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
3754 } catch (Exception e) {
3755 Slog.w(TAG, "Exception when doing dexopt : ", e);
3759 //error from installer
3760 return DEX_OPT_FAILED;
3764 return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
3767 private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
3768 boolean inclDependencies) {
3769 HashSet<String> done;
3770 boolean performed = false;
3771 if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
3772 done = new HashSet<String>();
3773 done.add(pkg.packageName);
3777 return performDexOptLI(pkg, forceDex, defer, done);
3780 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
3781 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3782 Slog.w(TAG, "Unable to update from " + oldPkg.name
3783 + " to " + newPkg.packageName
3784 + ": old package not in system partition");
3786 } else if (mPackages.get(oldPkg.name) != null) {
3787 Slog.w(TAG, "Unable to update from " + oldPkg.name
3788 + " to " + newPkg.packageName
3789 + ": old package still exists");
3795 File getDataPathForUser(int userId) {
3796 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
3799 private void writeAppwithABI2Internal(String fileName, HashMap<Integer, String> map) {
3801 FileOutputStream out = null;
3802 File appDataDir = new File("/data/data");
3805 File tempFile = File.createTempFile("tmp", "tmp", appDataDir);
3806 String tempFilePath = tempFile.getPath();
3807 outputFile = new File(fileName);
3808 if (FileUtils.setPermissions(tempFilePath,
3809 FileUtils.S_IRUSR | FileUtils.S_IWUSR |
3810 FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1) != 0
3811 || !tempFile.renameTo(outputFile)) {
3814 out = new FileOutputStream(outputFile);
3815 Iterator<HashMap.Entry<Integer, String>>
3816 it = map.entrySet().iterator();
3817 while (it.hasNext()) {
3818 HashMap.Entry<Integer, String> ent = it.next();
3819 int userID = ent.getKey().intValue();
3820 out.write(userID & 0xff);
3821 out.write((userID>>8) & 0xff);
3822 out.write((userID>>16) & 0xff);
3823 out.write((userID>>24) & 0xff);
3824 Slog.i(TAG, "Data written:"+ userID);
3826 } catch (Exception e) {
3827 Slog.e(TAG, "File Access Error: Not Able to write Data into " + fileName);
3832 Slog.i(TAG, "Data written into " + fileName);
3834 } catch (IOException e) {}
3838 private void writeAppwithABI2() {
3839 writeAppwithABI2Internal(new String("/data/data/.appwithABI2"), mPackagesMatchABI2);
3842 private void writeAppwithABI2Neon() {
3843 writeAppwithABI2Internal(new String("/data/data/.appwithABI2neon"), mPackagesMatchABI2Neon);
3846 private File getDataPathForPackage(String packageName, int userId) {
3848 * Until we fully support multiple users, return the directory we
3849 * previously would have. The PackageManagerTests will need to be
3850 * revised when this is changed back..
3853 return new File(mAppDataDir, packageName);
3855 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
3856 + File.separator + packageName);
3860 private int createDataDirsLI(String packageName, int uid, String seinfo) {
3861 int[] users = sUserManager.getUserIds();
3862 int res = mInstaller.install(packageName, uid, uid, seinfo);
3866 for (int user : users) {
3868 res = mInstaller.createUserData(packageName,
3869 UserHandle.getUid(user, uid), user);
3878 private int removeDataDirsLI(String packageName) {
3879 int[] users = sUserManager.getUserIds();
3881 for (int user : users) {
3882 int resInner = mInstaller.remove(packageName, user);
3888 final File nativeLibraryFile = new File(mAppLibInstallDir, packageName);
3889 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
3890 if (!nativeLibraryFile.delete()) {
3891 Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath());
3897 private int addSharedLibraryLPw(final SharedLibraryEntry file, int num,
3898 PackageParser.Package changingLib) {
3899 if (file.path != null) {
3900 mTmpSharedLibraries[num] = file.path;
3903 PackageParser.Package p = mPackages.get(file.apk);
3904 if (changingLib != null && changingLib.packageName.equals(file.apk)) {
3905 // If we are doing this while in the middle of updating a library apk,
3906 // then we need to make sure to use that new apk for determining the
3907 // dependencies here. (We haven't yet finished committing the new apk
3908 // to the package manager state.)
3909 if (p == null || p.packageName.equals(changingLib.packageName)) {
3914 String path = p.mPath;
3915 for (int i=0; i<num; i++) {
3916 if (mTmpSharedLibraries[i].equals(path)) {
3920 mTmpSharedLibraries[num] = p.mPath;
3926 private boolean updateSharedLibrariesLPw(PackageParser.Package pkg,
3927 PackageParser.Package changingLib) {
3928 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
3929 if (mTmpSharedLibraries == null ||
3930 mTmpSharedLibraries.length < mSharedLibraries.size()) {
3931 mTmpSharedLibraries = new String[mSharedLibraries.size()];
3934 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
3935 for (int i=0; i<N; i++) {
3936 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
3938 Slog.e(TAG, "Package " + pkg.packageName
3939 + " requires unavailable shared library "
3940 + pkg.usesLibraries.get(i) + "; failing!");
3941 mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
3944 num = addSharedLibraryLPw(file, num, changingLib);
3946 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
3947 for (int i=0; i<N; i++) {
3948 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
3950 Slog.w(TAG, "Package " + pkg.packageName
3951 + " desires unavailable shared library "
3952 + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
3954 num = addSharedLibraryLPw(file, num, changingLib);
3958 pkg.usesLibraryFiles = new String[num];
3959 System.arraycopy(mTmpSharedLibraries, 0,
3960 pkg.usesLibraryFiles, 0, num);
3962 pkg.usesLibraryFiles = null;
3968 private static boolean hasString(List<String> list, List<String> which) {
3972 for (int i=list.size()-1; i>=0; i--) {
3973 for (int j=which.size()-1; j>=0; j--) {
3974 if (which.get(j).equals(list.get(i))) {
3982 private void updateAllSharedLibrariesLPw() {
3983 for (PackageParser.Package pkg : mPackages.values()) {
3984 updateSharedLibrariesLPw(pkg, null);
3988 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
3989 PackageParser.Package changingPkg) {
3990 ArrayList<PackageParser.Package> res = null;
3991 for (PackageParser.Package pkg : mPackages.values()) {
3992 if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
3993 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
3995 res = new ArrayList<PackageParser.Package>();
3998 updateSharedLibrariesLPw(pkg, changingPkg);
4004 private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
4005 int parseFlags, int scanMode, long currentTime, UserHandle user) {
4006 File scanFile = new File(pkg.mScanPath);
4007 if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
4008 pkg.applicationInfo.publicSourceDir == null) {
4009 // Bail out. The resource and code paths haven't been set.
4010 Slog.w(TAG, " Code and resource paths haven't been set correctly");
4011 mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4014 mScanningPath = scanFile;
4016 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4017 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
4020 if (pkg.packageName.equals("android")) {
4021 synchronized (mPackages) {
4022 if (mAndroidApplication != null) {
4023 Slog.w(TAG, "*************************************************");
4024 Slog.w(TAG, "Core android package being redefined. Skipping.");
4025 Slog.w(TAG, " file=" + mScanningPath);
4026 Slog.w(TAG, "*************************************************");
4027 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4031 // Set up information for our fall-back user intent resolution
4033 mPlatformPackage = pkg;
4034 pkg.mVersionCode = mSdkVersion;
4035 mAndroidApplication = pkg.applicationInfo;
4036 mResolveActivity.applicationInfo = mAndroidApplication;
4037 mResolveActivity.name = ResolverActivity.class.getName();
4038 mResolveActivity.packageName = mAndroidApplication.packageName;
4039 mResolveActivity.processName = "system:ui";
4040 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
4041 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
4042 mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
4043 mResolveActivity.exported = true;
4044 mResolveActivity.enabled = true;
4045 mResolveInfo.activityInfo = mResolveActivity;
4046 mResolveInfo.priority = 0;
4047 mResolveInfo.preferredOrder = 0;
4048 mResolveInfo.match = 0;
4049 mResolveComponentName = new ComponentName(
4050 mAndroidApplication.packageName, mResolveActivity.name);
4054 if (DEBUG_PACKAGE_SCANNING) {
4055 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4056 Log.d(TAG, "Scanning package " + pkg.packageName);
4059 if (mPackages.containsKey(pkg.packageName)
4060 || mSharedLibraries.containsKey(pkg.packageName)) {
4061 Slog.w(TAG, "Application package " + pkg.packageName
4062 + " already installed. Skipping duplicate.");
4063 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4067 // Initialize package source and resource directories
4068 File destCodeFile = new File(pkg.applicationInfo.sourceDir);
4069 File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
4071 SharedUserSetting suid = null;
4072 PackageSetting pkgSetting = null;
4074 if (!isSystemApp(pkg)) {
4075 // Only system apps can use these features.
4076 pkg.mOriginalPackages = null;
4077 pkg.mRealPackage = null;
4078 pkg.mAdoptPermissions = null;
4082 synchronized (mPackages) {
4083 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4084 // Check all shared libraries and map to their actual file path.
4085 // We only do this here for apps not on a system dir, because those
4086 // are the only ones that can fail an install due to this. We
4087 // will take care of the system apps by updating all of their
4088 // library paths after the scan is done.
4089 if (!updateSharedLibrariesLPw(pkg, null)) {
4094 if (pkg.mSharedUserId != null) {
4095 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId,
4096 pkg.applicationInfo.flags, true);
4098 Slog.w(TAG, "Creating application package " + pkg.packageName
4099 + " for shared user failed");
4100 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4103 if (DEBUG_PACKAGE_SCANNING) {
4104 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4105 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
4106 + "): packages=" + suid.packages);
4110 // Check if we are renaming from an original package name.
4111 PackageSetting origPackage = null;
4112 String realName = null;
4113 if (pkg.mOriginalPackages != null) {
4114 // This package may need to be renamed to a previously
4115 // installed name. Let's check on that...
4116 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
4117 if (pkg.mOriginalPackages.contains(renamed)) {
4118 // This package had originally been installed as the
4119 // original name, and we have already taken care of
4120 // transitioning to the new one. Just update the new
4121 // one to continue using the old name.
4122 realName = pkg.mRealPackage;
4123 if (!pkg.packageName.equals(renamed)) {
4124 // Callers into this function may have already taken
4125 // care of renaming the package; only do it here if
4126 // it is not already done.
4127 pkg.setPackageName(renamed);
4131 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
4132 if ((origPackage = mSettings.peekPackageLPr(
4133 pkg.mOriginalPackages.get(i))) != null) {
4134 // We do have the package already installed under its
4135 // original name... should we use it?
4136 if (!verifyPackageUpdateLPr(origPackage, pkg)) {
4137 // New package is not compatible with original.
4140 } else if (origPackage.sharedUser != null) {
4141 // Make sure uid is compatible between packages.
4142 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
4143 Slog.w(TAG, "Unable to migrate data from " + origPackage.name
4144 + " to " + pkg.packageName + ": old uid "
4145 + origPackage.sharedUser.name
4146 + " differs from " + pkg.mSharedUserId);
4151 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
4152 + pkg.packageName + " to old name " + origPackage.name);
4160 if (mTransferedPackages.contains(pkg.packageName)) {
4161 Slog.w(TAG, "Package " + pkg.packageName
4162 + " was transferred to another, but its .apk remains");
4165 String abi2 = SystemProperties.get("ro.product.cpu.abi2");
4166 if (abi2.length() != 0) {
4167 // abi2 is set, houdini is enabled
4168 PackageSetting p = mSettings.mPackages.get(pkg.packageName);
4169 if ((p != null) && (!p.codePath.equals(destCodeFile))){
4171 // Already existing package. Make sure not upgrade to black list
4172 int result = NativeLibraryHelper.listNativeBinariesLI(scanFile);
4174 if (result == PackageManager.INSTALL_ABI2_SUCCEEDED) {
4175 ICheckExt check = new CheckExt();
4176 if(check.doCheck(pkg.packageName, new String("filter"))){
4177 Slog.i(TAG, "Reject application in black list::" + pkg.packageName);
4178 mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4186 // Just create the setting, don't add it yet. For already existing packages
4187 // the PkgSetting exists already and doesn't have to be created.
4188 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
4189 destResourceFile, pkg.applicationInfo.nativeLibraryDir,
4190 pkg.applicationInfo.flags, user, false);
4191 if (pkgSetting == null) {
4192 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
4193 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4197 if (pkgSetting.origPackage != null) {
4198 // If we are first transitioning from an original package,
4199 // fix up the new package's name now. We need to do this after
4200 // looking up the package under its new name, so getPackageLP
4201 // can take care of fiddling things correctly.
4202 pkg.setPackageName(origPackage.name);
4204 // File a report about this.
4205 String msg = "New package " + pkgSetting.realName
4206 + " renamed to replace old package " + pkgSetting.name;
4207 reportSettingsProblem(Log.WARN, msg);
4209 // Make a note of it.
4210 mTransferedPackages.add(origPackage.name);
4212 // No longer need to retain this.
4213 pkgSetting.origPackage = null;
4216 if (realName != null) {
4217 // Make a note of it.
4218 mTransferedPackages.add(pkg.packageName);
4221 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
4222 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
4225 if (mFoundPolicyFile) {
4226 SELinuxMMAC.assignSeinfoValue(pkg);
4229 pkg.applicationInfo.uid = pkgSetting.appId;
4230 pkg.mExtras = pkgSetting;
4232 if (!verifySignaturesLP(pkgSetting, pkg)) {
4233 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4236 // The signature has changed, but this package is in the system
4237 // image... let's recover!
4238 pkgSetting.signatures.mSignatures = pkg.mSignatures;
4239 // However... if this package is part of a shared user, but it
4240 // doesn't match the signature of the shared user, let's fail.
4241 // What this means is that you can't change the signatures
4242 // associated with an overall shared user, which doesn't seem all
4243 // that unreasonable.
4244 if (pkgSetting.sharedUser != null) {
4245 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4246 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
4247 Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
4248 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
4252 // File a report about this.
4253 String msg = "System package " + pkg.packageName
4254 + " signature changed; retaining data.";
4255 reportSettingsProblem(Log.WARN, msg);
4258 // Verify that this new package doesn't have any content providers
4259 // that conflict with existing packages. Only do this if the
4260 // package isn't already installed, since we don't want to break
4261 // things that are installed.
4262 if ((scanMode&SCAN_NEW_INSTALL) != 0) {
4263 final int N = pkg.providers.size();
4265 for (i=0; i<N; i++) {
4266 PackageParser.Provider p = pkg.providers.get(i);
4267 if (p.info.authority != null) {
4268 String names[] = p.info.authority.split(";");
4269 for (int j = 0; j < names.length; j++) {
4270 if (mProviders.containsKey(names[j])) {
4271 PackageParser.Provider other = mProviders.get(names[j]);
4272 Slog.w(TAG, "Can't install because provider name " + names[j] +
4273 " (in package " + pkg.applicationInfo.packageName +
4274 ") is already used by "
4275 + ((other != null && other.getComponentName() != null)
4276 ? other.getComponentName().getPackageName() : "?"));
4277 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
4285 if (pkg.mAdoptPermissions != null) {
4286 // This package wants to adopt ownership of permissions from
4288 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
4289 final String origName = pkg.mAdoptPermissions.get(i);
4290 final PackageSetting orig = mSettings.peekPackageLPr(origName);
4292 if (verifyPackageUpdateLPr(orig, pkg)) {
4293 Slog.i(TAG, "Adopting permissions from " + origName + " to "
4295 mSettings.transferPermissionsLPw(origName, pkg.packageName);
4302 final String pkgName = pkg.packageName;
4304 final long scanFileTime = scanFile.lastModified();
4305 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
4306 pkg.applicationInfo.processName = fixProcessName(
4307 pkg.applicationInfo.packageName,
4308 pkg.applicationInfo.processName,
4309 pkg.applicationInfo.uid);
4312 if (mPlatformPackage == pkg) {
4313 // The system package is special.
4314 dataPath = new File (Environment.getDataDirectory(), "system");
4315 pkg.applicationInfo.dataDir = dataPath.getPath();
4317 // This is a normal package, need to make its data directory.
4318 dataPath = getDataPathForPackage(pkg.packageName, 0);
4320 boolean uidError = false;
4322 if (dataPath.exists()) {
4325 StructStat stat = Libcore.os.stat(dataPath.getPath());
4326 currentUid = stat.st_uid;
4327 } catch (ErrnoException e) {
4328 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
4331 // If we have mismatched owners for the data path, we have a problem.
4332 if (currentUid != pkg.applicationInfo.uid) {
4333 boolean recovered = false;
4334 if (currentUid == 0) {
4335 // The directory somehow became owned by root. Wow.
4336 // This is probably because the system was stopped while
4337 // installd was in the middle of messing with its libs
4338 // directory. Ask installd to fix that.
4339 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
4340 pkg.applicationInfo.uid);
4343 String msg = "Package " + pkg.packageName
4344 + " unexpectedly changed to uid 0; recovered to " +
4345 + pkg.applicationInfo.uid;
4346 reportSettingsProblem(Log.WARN, msg);
4349 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4350 || (scanMode&SCAN_BOOTING) != 0)) {
4351 // If this is a system app, we can at least delete its
4352 // current data so the application will still work.
4353 int ret = removeDataDirsLI(pkgName);
4355 // TODO: Kill the processes first
4357 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4358 ? "System package " : "Third party package ";
4359 String msg = prefix + pkg.packageName
4360 + " has changed from uid: "
4361 + currentUid + " to "
4362 + pkg.applicationInfo.uid + "; old data erased";
4363 reportSettingsProblem(Log.WARN, msg);
4366 // And now re-install the app.
4367 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4368 pkg.applicationInfo.seinfo);
4370 // Ack should not happen!
4371 msg = prefix + pkg.packageName
4372 + " could not have data directory re-created after delete.";
4373 reportSettingsProblem(Log.WARN, msg);
4374 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4379 mHasSystemUidErrors = true;
4381 } else if (!recovered) {
4382 // If we allow this install to proceed, we will be broken.
4384 mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
4388 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
4389 + pkg.applicationInfo.uid + "/fs_"
4391 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
4392 String msg = "Package " + pkg.packageName
4393 + " has mismatched uid: "
4394 + currentUid + " on disk, "
4395 + pkg.applicationInfo.uid + " in settings";
4397 synchronized (mPackages) {
4398 mSettings.mReadMessages.append(msg);
4399 mSettings.mReadMessages.append('\n');
4401 if (!pkgSetting.uidError) {
4402 reportSettingsProblem(Log.ERROR, msg);
4407 pkg.applicationInfo.dataDir = dataPath.getPath();
4409 if (DEBUG_PACKAGE_SCANNING) {
4410 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4411 Log.v(TAG, "Want this data dir: " + dataPath);
4413 //invoke installer to do the actual installation
4414 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4415 pkg.applicationInfo.seinfo);
4417 // Error from installer
4418 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4422 if (dataPath.exists()) {
4423 pkg.applicationInfo.dataDir = dataPath.getPath();
4425 Slog.w(TAG, "Unable to create data directory: " + dataPath);
4426 pkg.applicationInfo.dataDir = null;
4431 * Set the data dir to the default "/data/data/<package name>/lib"
4432 * if we got here without anyone telling us different (e.g., apps
4433 * stored on SD card have their native libraries stored in the ASEC
4434 * container with the APK).
4436 * This happens during an upgrade from a package settings file that
4437 * doesn't have a native library path attribute at all.
4439 if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
4440 if (pkgSetting.nativeLibraryPathString == null) {
4441 setInternalAppNativeLibraryPath(pkg, pkgSetting);
4443 pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
4447 pkgSetting.uidError = uidError;
4450 String path = scanFile.getPath();
4451 /* Note: We don't want to unpack the native binaries for
4452 * system applications, unless they have been updated
4453 * (the binaries are already under /system/lib).
4454 * Also, don't unpack libs for apps on the external card
4455 * since they should have their libraries in the ASEC
4456 * container already.
4458 * In other words, we're going to unpack the binaries
4459 * only for non-system apps and system app upgrades.
4461 if (pkg.applicationInfo.nativeLibraryDir != null) {
4463 File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
4464 final String dataPathString = dataPath.getCanonicalPath();
4466 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4468 * Upgrading from a previous version of the OS sometimes
4469 * leaves native libraries in the /data/data/<app>/lib
4470 * directory for system apps even when they shouldn't be.
4471 * Recent changes in the JNI library search path
4472 * necessitates we remove those to match previous behavior.
4474 if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
4475 Log.i(TAG, "removed obsolete native libraries for system package "
4479 if (!isForwardLocked(pkg) && !isExternal(pkg)) {
4481 * Update native library dir if it starts with
4484 if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
4485 setInternalAppNativeLibraryPath(pkg, pkgSetting);
4486 nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
4490 int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir);
4491 Integer pkgUidInt = new Integer(pkg.applicationInfo.uid);
4492 if (copyRet == PackageManager.INSTALL_SUCCEEDED) {
4493 String abi2 = SystemProperties.get("ro.product.cpu.abi2");
4494 if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(pkgUidInt)) {
4495 Slog.i(TAG, "Replace package with primary ABI Library");
4496 mPackagesMatchABI2.remove(pkgUidInt);
4498 if (mPackagesMatchABI2Neon.containsKey(pkgUidInt)) {
4499 mPackagesMatchABI2Neon.remove(pkgUidInt);
4500 writeAppwithABI2Neon();
4503 } else if (copyRet == PackageManager.INSTALL_ABI2_SUCCEEDED) {
4504 ICheckExt check = new CheckExt();
4505 if(check.doCheck(pkgName, new String("filter"))) {
4506 Slog.i(TAG, "Package with second ABI is in black list: " + pkgUidInt + pkg.applicationInfo.processName);
4507 mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4510 Slog.i(TAG, "Package installed with second ABI Library: " + pkgUidInt + pkg.applicationInfo.processName);
4511 mPackagesMatchABI2.put(pkgUidInt, pkg.applicationInfo.processName);
4513 if (check.doCheck(pkgName, new String("neon"))) {
4514 mPackagesMatchABI2Neon.put(pkgUidInt, pkg.applicationInfo.processName);
4515 writeAppwithABI2Neon();
4518 Slog.e(TAG, "Unable to copy native libraries");
4519 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4522 } catch (IOException e) {
4523 Slog.e(TAG, "Unable to copy native libraries", e);
4524 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4529 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
4530 final int[] userIds = sUserManager.getUserIds();
4531 synchronized (mInstallLock) {
4532 for (int userId : userIds) {
4533 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
4534 pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
4535 Slog.w(TAG, "Failed linking native library dir (user=" + userId
4537 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4543 } catch (IOException ioe) {
4544 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
4547 pkg.mScanPath = path;
4549 if ((scanMode&SCAN_NO_DEX) == 0) {
4550 if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
4551 == DEX_OPT_FAILED) {
4552 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
4557 if (mFactoryTest && pkg.requestedPermissions.contains(
4558 android.Manifest.permission.FACTORY_TEST)) {
4559 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
4562 ArrayList<PackageParser.Package> clientLibPkgs = null;
4565 synchronized (mPackages) {
4566 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
4567 // Only system apps can add new shared libraries.
4568 if (pkg.libraryNames != null) {
4569 for (int i=0; i<pkg.libraryNames.size(); i++) {
4570 String name = pkg.libraryNames.get(i);
4571 boolean allowed = false;
4572 if (isUpdatedSystemApp(pkg)) {
4573 // New library entries can only be added through the
4574 // system image. This is important to get rid of a lot
4575 // of nasty edge cases: for example if we allowed a non-
4576 // system update of the app to add a library, then uninstalling
4577 // the update would make the library go away, and assumptions
4578 // we made such as through app install filtering would now
4579 // have allowed apps on the device which aren't compatible
4580 // with it. Better to just have the restriction here, be
4581 // conservative, and create many fewer cases that can negatively
4582 // impact the user experience.
4583 final PackageSetting sysPs = mSettings
4584 .getDisabledSystemPkgLPr(pkg.packageName);
4585 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
4586 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
4587 if (name.equals(sysPs.pkg.libraryNames.get(j))) {
4598 if (!mSharedLibraries.containsKey(name)) {
4599 mSharedLibraries.put(name, new SharedLibraryEntry(null,
4601 } else if (!name.equals(pkg.packageName)) {
4602 Slog.w(TAG, "Package " + pkg.packageName + " library "
4603 + name + " already exists; skipping");
4606 Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
4607 + name + " that is not declared on system image; skipping");
4610 if ((scanMode&SCAN_BOOTING) == 0) {
4611 // If we are not booting, we need to update any applications
4612 // that are clients of our shared library. If we are booting,
4613 // this will all be done once the scan is complete.
4614 clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
4620 // We also need to dexopt any apps that are dependent on this library. Note that
4621 // if these fail, we should abort the install since installing the library will
4622 // result in some apps being broken.
4623 if (clientLibPkgs != null) {
4624 if ((scanMode&SCAN_NO_DEX) == 0) {
4625 for (int i=0; i<clientLibPkgs.size(); i++) {
4626 PackageParser.Package clientPkg = clientLibPkgs.get(i);
4627 if (performDexOptLI(clientPkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
4628 == DEX_OPT_FAILED) {
4629 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
4636 // Request the ActivityManager to kill the process(only for existing packages)
4637 // so that we do not end up in a confused state while the user is still using the older
4638 // version of the application while the new one gets installed.
4639 if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
4640 killApplication(pkg.applicationInfo.packageName,
4641 pkg.applicationInfo.uid);
4644 // Also need to kill any apps that are dependent on the library.
4645 if (clientLibPkgs != null) {
4646 for (int i=0; i<clientLibPkgs.size(); i++) {
4647 PackageParser.Package clientPkg = clientLibPkgs.get(i);
4648 killApplication(clientPkg.applicationInfo.packageName,
4649 clientPkg.applicationInfo.uid);
4654 synchronized (mPackages) {
4655 // We don't expect installation to fail beyond this point,
4656 if ((scanMode&SCAN_MONITOR) != 0) {
4657 mAppDirs.put(pkg.mPath, pkg);
4659 // Add the new setting to mSettings
4660 mSettings.insertPackageSettingLPw(pkgSetting, pkg);
4661 // Add the new setting to mPackages
4662 mPackages.put(pkg.applicationInfo.packageName, pkg);
4663 // Make sure we don't accidentally delete its data.
4664 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
4665 while (iter.hasNext()) {
4666 PackageCleanItem item = iter.next();
4667 if (pkgName.equals(item.packageName)) {
4672 // Take care of first install / last update times.
4673 if (currentTime != 0) {
4674 if (pkgSetting.firstInstallTime == 0) {
4675 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
4676 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
4677 pkgSetting.lastUpdateTime = currentTime;
4679 } else if (pkgSetting.firstInstallTime == 0) {
4680 // We need *something*. Take time time stamp of the file.
4681 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
4682 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
4683 if (scanFileTime != pkgSetting.timeStamp) {
4684 // A package on the system image has changed; consider this
4686 pkgSetting.lastUpdateTime = scanFileTime;
4690 int N = pkg.providers.size();
4691 StringBuilder r = null;
4693 for (i=0; i<N; i++) {
4694 PackageParser.Provider p = pkg.providers.get(i);
4695 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
4696 p.info.processName, pkg.applicationInfo.uid);
4697 mProvidersByComponent.put(new ComponentName(p.info.packageName,
4699 p.syncable = p.info.isSyncable;
4700 if (p.info.authority != null) {
4701 String names[] = p.info.authority.split(";");
4702 p.info.authority = null;
4703 for (int j = 0; j < names.length; j++) {
4704 if (j == 1 && p.syncable) {
4705 // We only want the first authority for a provider to possibly be
4706 // syncable, so if we already added this provider using a different
4707 // authority clear the syncable flag. We copy the provider before
4708 // changing it because the mProviders object contains a reference
4709 // to a provider that we don't want to change.
4710 // Only do this for the second authority since the resulting provider
4711 // object can be the same for all future authorities for this provider.
4712 p = new PackageParser.Provider(p);
4715 if (!mProviders.containsKey(names[j])) {
4716 mProviders.put(names[j], p);
4717 if (p.info.authority == null) {
4718 p.info.authority = names[j];
4720 p.info.authority = p.info.authority + ";" + names[j];
4722 if (DEBUG_PACKAGE_SCANNING) {
4723 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4724 Log.d(TAG, "Registered content provider: " + names[j]
4725 + ", className = " + p.info.name + ", isSyncable = "
4726 + p.info.isSyncable);
4729 PackageParser.Provider other = mProviders.get(names[j]);
4730 Slog.w(TAG, "Skipping provider name " + names[j] +
4731 " (in package " + pkg.applicationInfo.packageName +
4732 "): name already used by "
4733 + ((other != null && other.getComponentName() != null)
4734 ? other.getComponentName().getPackageName() : "?"));
4738 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4740 r = new StringBuilder(256);
4744 r.append(p.info.name);
4748 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
4751 N = pkg.services.size();
4753 for (i=0; i<N; i++) {
4754 PackageParser.Service s = pkg.services.get(i);
4755 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
4756 s.info.processName, pkg.applicationInfo.uid);
4757 mServices.addService(s);
4758 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4760 r = new StringBuilder(256);
4764 r.append(s.info.name);
4768 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
4771 N = pkg.receivers.size();
4773 for (i=0; i<N; i++) {
4774 PackageParser.Activity a = pkg.receivers.get(i);
4775 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4776 a.info.processName, pkg.applicationInfo.uid);
4777 mReceivers.addActivity(a, "receiver");
4778 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4780 r = new StringBuilder(256);
4784 r.append(a.info.name);
4788 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
4791 N = pkg.activities.size();
4793 for (i=0; i<N; i++) {
4794 PackageParser.Activity a = pkg.activities.get(i);
4795 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4796 a.info.processName, pkg.applicationInfo.uid);
4797 mActivities.addActivity(a, "activity");
4798 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4800 r = new StringBuilder(256);
4804 r.append(a.info.name);
4808 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
4811 N = pkg.permissionGroups.size();
4813 for (i=0; i<N; i++) {
4814 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
4815 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
4817 mPermissionGroups.put(pg.info.name, pg);
4818 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4820 r = new StringBuilder(256);
4824 r.append(pg.info.name);
4827 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
4828 + pg.info.packageName + " ignored: original from "
4829 + cur.info.packageName);
4830 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4832 r = new StringBuilder(256);
4837 r.append(pg.info.name);
4842 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r);
4845 N = pkg.permissions.size();
4847 for (i=0; i<N; i++) {
4848 PackageParser.Permission p = pkg.permissions.get(i);
4849 HashMap<String, BasePermission> permissionMap =
4850 p.tree ? mSettings.mPermissionTrees
4851 : mSettings.mPermissions;
4852 p.group = mPermissionGroups.get(p.info.group);
4853 if (p.info.group == null || p.group != null) {
4854 BasePermission bp = permissionMap.get(p.info.name);
4856 bp = new BasePermission(p.info.name, p.info.packageName,
4857 BasePermission.TYPE_NORMAL);
4858 permissionMap.put(p.info.name, bp);
4860 if (bp.perm == null) {
4861 if (bp.sourcePackage == null
4862 || bp.sourcePackage.equals(p.info.packageName)) {
4863 BasePermission tree = findPermissionTreeLP(p.info.name);
4865 || tree.sourcePackage.equals(p.info.packageName)) {
4866 bp.packageSetting = pkgSetting;
4868 bp.uid = pkg.applicationInfo.uid;
4869 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4871 r = new StringBuilder(256);
4875 r.append(p.info.name);
4878 Slog.w(TAG, "Permission " + p.info.name + " from package "
4879 + p.info.packageName + " ignored: base tree "
4880 + tree.name + " is from package "
4881 + tree.sourcePackage);
4884 Slog.w(TAG, "Permission " + p.info.name + " from package "
4885 + p.info.packageName + " ignored: original from "
4886 + bp.sourcePackage);
4888 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4890 r = new StringBuilder(256);
4895 r.append(p.info.name);
4898 bp.protectionLevel = p.info.protectionLevel;
4901 Slog.w(TAG, "Permission " + p.info.name + " from package "
4902 + p.info.packageName + " ignored: no group "
4907 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
4910 N = pkg.instrumentation.size();
4912 for (i=0; i<N; i++) {
4913 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
4914 a.info.packageName = pkg.applicationInfo.packageName;
4915 a.info.sourceDir = pkg.applicationInfo.sourceDir;
4916 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
4917 a.info.dataDir = pkg.applicationInfo.dataDir;
4918 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
4919 mInstrumentation.put(a.getComponentName(), a);
4920 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4922 r = new StringBuilder(256);
4926 r.append(a.info.name);
4930 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
4933 if (pkg.protectedBroadcasts != null) {
4934 N = pkg.protectedBroadcasts.size();
4935 for (i=0; i<N; i++) {
4936 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
4940 pkgSetting.setTimeStamp(scanFileTime);
4946 private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
4947 PackageSetting pkgSetting) {
4948 final String apkLibPath = getApkName(pkgSetting.codePathString);
4949 final String nativeLibraryPath = new File(mAppLibInstallDir, apkLibPath).getPath();
4950 pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
4951 pkgSetting.nativeLibraryPathString = nativeLibraryPath;
4954 private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
4955 throws IOException {
4956 if (!nativeLibraryDir.isDirectory()) {
4957 nativeLibraryDir.delete();
4959 if (!nativeLibraryDir.mkdir()) {
4960 throw new IOException("Cannot create " + nativeLibraryDir.getPath());
4964 Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
4966 } catch (ErrnoException e) {
4967 throw new IOException("Cannot chmod native library directory "
4968 + nativeLibraryDir.getPath(), e);
4970 } else if (!SELinux.restorecon(nativeLibraryDir)) {
4971 throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath());
4975 * If this is an internal application or our nativeLibraryPath points to
4976 * the app-lib directory, unpack the libraries if necessary.
4978 return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
4981 private void killApplication(String pkgName, int appId) {
4982 // Request the ActivityManager to kill the process(only for existing packages)
4983 // so that we do not end up in a confused state while the user is still using the older
4984 // version of the application while the new one gets installed.
4985 IActivityManager am = ActivityManagerNative.getDefault();
4988 am.killApplicationWithAppId(pkgName, appId);
4989 } catch (RemoteException e) {
4994 void removePackageLI(PackageSetting ps, boolean chatty) {
4995 if (DEBUG_INSTALL) {
4997 Log.d(TAG, "Removing package " + ps.name);
5001 synchronized (mPackages) {
5002 mPackages.remove(ps.name);
5003 if (ps.codePathString != null) {
5004 mAppDirs.remove(ps.codePathString);
5007 final PackageParser.Package pkg = ps.pkg;
5009 cleanPackageDataStructuresLILPw(pkg, chatty);
5011 String abi2 = SystemProperties.get("ro.product.cpu.abi2");
5012 Integer pkgUidInt = new Integer(pkg.applicationInfo.uid);
5013 if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(pkgUidInt)) {
5014 Slog.i(TAG, "Uninstall package with second ABI Library");
5015 mPackagesMatchABI2.remove(pkgUidInt);
5017 if (mPackagesMatchABI2Neon.containsKey(pkgUidInt)) {
5018 mPackagesMatchABI2Neon.remove(pkgUidInt);
5019 writeAppwithABI2Neon();
5027 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
5028 if (DEBUG_INSTALL) {
5030 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
5034 synchronized (mPackages) {
5035 mPackages.remove(pkg.applicationInfo.packageName);
5036 if (pkg.mPath != null) {
5037 mAppDirs.remove(pkg.mPath);
5039 cleanPackageDataStructuresLILPw(pkg, chatty);
5041 String abi2 = SystemProperties.get("ro.product.cpu.abi2");
5042 if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(new Integer(pkg.applicationInfo.uid))) {
5043 Slog.i(TAG, "Uninstall package with second ABI Library");
5044 mPackagesMatchABI2.remove(new Integer(pkg.applicationInfo.uid));
5046 if (mPackagesMatchABI2Neon.containsKey(new Integer(pkg.applicationInfo.uid))) {
5047 mPackagesMatchABI2Neon.remove(new Integer(pkg.applicationInfo.uid));
5048 writeAppwithABI2Neon();
5055 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
5056 int N = pkg.providers.size();
5057 StringBuilder r = null;
5059 for (i=0; i<N; i++) {
5060 PackageParser.Provider p = pkg.providers.get(i);
5061 mProvidersByComponent.remove(new ComponentName(p.info.packageName,
5063 if (p.info.authority == null) {
5065 /* There was another ContentProvider with this authority when
5066 * this app was installed so this authority is null,
5067 * Ignore it as we don't have to unregister the provider.
5071 String names[] = p.info.authority.split(";");
5072 for (int j = 0; j < names.length; j++) {
5073 if (mProviders.get(names[j]) == p) {
5074 mProviders.remove(names[j]);
5077 Log.d(TAG, "Unregistered content provider: " + names[j]
5078 + ", className = " + p.info.name + ", isSyncable = "
5079 + p.info.isSyncable);
5083 if (DEBUG_REMOVE && chatty) {
5085 r = new StringBuilder(256);
5089 r.append(p.info.name);
5093 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
5096 N = pkg.services.size();
5098 for (i=0; i<N; i++) {
5099 PackageParser.Service s = pkg.services.get(i);
5100 mServices.removeService(s);
5103 r = new StringBuilder(256);
5107 r.append(s.info.name);
5111 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
5114 N = pkg.receivers.size();
5116 for (i=0; i<N; i++) {
5117 PackageParser.Activity a = pkg.receivers.get(i);
5118 mReceivers.removeActivity(a, "receiver");
5119 if (DEBUG_REMOVE && chatty) {
5121 r = new StringBuilder(256);
5125 r.append(a.info.name);
5129 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
5132 N = pkg.activities.size();
5134 for (i=0; i<N; i++) {
5135 PackageParser.Activity a = pkg.activities.get(i);
5136 mActivities.removeActivity(a, "activity");
5137 if (DEBUG_REMOVE && chatty) {
5139 r = new StringBuilder(256);
5143 r.append(a.info.name);
5147 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
5150 N = pkg.permissions.size();
5152 for (i=0; i<N; i++) {
5153 PackageParser.Permission p = pkg.permissions.get(i);
5154 BasePermission bp = mSettings.mPermissions.get(p.info.name);
5156 bp = mSettings.mPermissionTrees.get(p.info.name);
5158 if (bp != null && bp.perm == p) {
5160 if (DEBUG_REMOVE && chatty) {
5162 r = new StringBuilder(256);
5166 r.append(p.info.name);
5171 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
5174 N = pkg.instrumentation.size();
5176 for (i=0; i<N; i++) {
5177 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
5178 mInstrumentation.remove(a.getComponentName());
5179 if (DEBUG_REMOVE && chatty) {
5181 r = new StringBuilder(256);
5185 r.append(a.info.name);
5189 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r);
5193 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5194 // Only system apps can hold shared libraries.
5195 if (pkg.libraryNames != null) {
5196 for (i=0; i<pkg.libraryNames.size(); i++) {
5197 String name = pkg.libraryNames.get(i);
5198 SharedLibraryEntry cur = mSharedLibraries.get(name);
5199 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
5200 mSharedLibraries.remove(name);
5201 if (DEBUG_REMOVE && chatty) {
5203 r = new StringBuilder(256);
5214 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r);
5218 private static final boolean isPackageFilename(String name) {
5219 return name != null && name.endsWith(".apk");
5222 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
5223 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
5224 if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
5231 static final int UPDATE_PERMISSIONS_ALL = 1<<0;
5232 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
5233 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
5235 private void updatePermissionsLPw(String changingPkg,
5236 PackageParser.Package pkgInfo, int flags) {
5237 // Make sure there are no dangling permission trees.
5238 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
5239 while (it.hasNext()) {
5240 final BasePermission bp = it.next();
5241 if (bp.packageSetting == null) {
5242 // We may not yet have parsed the package, so just see if
5243 // we still know about its settings.
5244 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5246 if (bp.packageSetting == null) {
5247 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
5248 + " from package " + bp.sourcePackage);
5250 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5251 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5252 Slog.i(TAG, "Removing old permission tree: " + bp.name
5253 + " from package " + bp.sourcePackage);
5254 flags |= UPDATE_PERMISSIONS_ALL;
5260 // Make sure all dynamic permissions have been assigned to a package,
5261 // and make sure there are no dangling permissions.
5262 it = mSettings.mPermissions.values().iterator();
5263 while (it.hasNext()) {
5264 final BasePermission bp = it.next();
5265 if (bp.type == BasePermission.TYPE_DYNAMIC) {
5266 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
5267 + bp.name + " pkg=" + bp.sourcePackage
5268 + " info=" + bp.pendingInfo);
5269 if (bp.packageSetting == null && bp.pendingInfo != null) {
5270 final BasePermission tree = findPermissionTreeLP(bp.name);
5271 if (tree != null && tree.perm != null) {
5272 bp.packageSetting = tree.packageSetting;
5273 bp.perm = new PackageParser.Permission(tree.perm.owner,
5274 new PermissionInfo(bp.pendingInfo));
5275 bp.perm.info.packageName = tree.perm.info.packageName;
5276 bp.perm.info.name = bp.name;
5281 if (bp.packageSetting == null) {
5282 // We may not yet have parsed the package, so just see if
5283 // we still know about its settings.
5284 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5286 if (bp.packageSetting == null) {
5287 Slog.w(TAG, "Removing dangling permission: " + bp.name
5288 + " from package " + bp.sourcePackage);
5290 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5291 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5292 Slog.i(TAG, "Removing old permission: " + bp.name
5293 + " from package " + bp.sourcePackage);
5294 flags |= UPDATE_PERMISSIONS_ALL;
5300 // Now update the permissions for all packages, in particular
5301 // replace the granted permissions of the system packages.
5302 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
5303 for (PackageParser.Package pkg : mPackages.values()) {
5304 if (pkg != pkgInfo) {
5305 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
5310 if (pkgInfo != null) {
5311 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
5315 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
5316 final PackageSetting ps = (PackageSetting) pkg.mExtras;
5320 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
5321 HashSet<String> origPermissions = gp.grantedPermissions;
5322 boolean changedPermission = false;
5325 ps.permissionsFixed = false;
5327 origPermissions = new HashSet<String>(gp.grantedPermissions);
5328 gp.grantedPermissions.clear();
5329 gp.gids = mGlobalGids;
5333 if (gp.gids == null) {
5334 gp.gids = mGlobalGids;
5337 final int N = pkg.requestedPermissions.size();
5338 for (int i=0; i<N; i++) {
5339 final String name = pkg.requestedPermissions.get(i);
5340 final boolean required = pkg.requestedPermissionsRequired.get(i);
5341 final BasePermission bp = mSettings.mPermissions.get(name);
5342 if (DEBUG_INSTALL) {
5344 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
5348 if (bp == null || bp.packageSetting == null) {
5349 Slog.w(TAG, "Unknown permission " + name
5350 + " in package " + pkg.packageName);
5354 final String perm = bp.name;
5356 boolean allowedSig = false;
5357 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
5358 if (level == PermissionInfo.PROTECTION_NORMAL
5359 || level == PermissionInfo.PROTECTION_DANGEROUS) {
5360 // We grant a normal or dangerous permission if any of the following
5362 // 1) The permission is required
5363 // 2) The permission is optional, but was granted in the past
5364 // 3) The permission is optional, but was requested by an
5365 // app in /system (not /data)
5367 // Otherwise, reject the permission.
5368 allowed = (required || origPermissions.contains(perm)
5369 || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
5370 } else if (bp.packageSetting == null) {
5371 // This permission is invalid; skip it.
5373 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
5374 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
5381 if (DEBUG_INSTALL) {
5383 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
5387 if (!isSystemApp(ps) && ps.permissionsFixed) {
5388 // If this is an existing, non-system package, then
5389 // we can't add any new permissions to it.
5390 if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
5391 // Except... if this is a permission that was added
5392 // to the platform (note: need to only do this when
5393 // updating the platform).
5394 allowed = isNewPlatformPermissionForPackage(perm, pkg);
5398 if (!gp.grantedPermissions.contains(perm)) {
5399 changedPermission = true;
5400 gp.grantedPermissions.add(perm);
5401 gp.gids = appendInts(gp.gids, bp.gids);
5402 } else if (!ps.haveGids) {
5403 gp.gids = appendInts(gp.gids, bp.gids);
5406 Slog.w(TAG, "Not granting permission " + perm
5407 + " to package " + pkg.packageName
5408 + " because it was previously installed without");
5411 if (gp.grantedPermissions.remove(perm)) {
5412 changedPermission = true;
5413 gp.gids = removeInts(gp.gids, bp.gids);
5414 Slog.i(TAG, "Un-granting permission " + perm
5415 + " from package " + pkg.packageName
5416 + " (protectionLevel=" + bp.protectionLevel
5417 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
5420 Slog.w(TAG, "Not granting permission " + perm
5421 + " to package " + pkg.packageName
5422 + " (protectionLevel=" + bp.protectionLevel
5423 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
5429 if ((changedPermission || replace) && !ps.permissionsFixed &&
5430 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
5431 // This is the first that we have heard about this package, so the
5432 // permissions we have now selected are fixed until explicitly
5434 ps.permissionsFixed = true;
5439 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
5440 boolean allowed = false;
5441 final int NP = PackageParser.NEW_PERMISSIONS.length;
5442 for (int ip=0; ip<NP; ip++) {
5443 final PackageParser.NewPermissionInfo npi
5444 = PackageParser.NEW_PERMISSIONS[ip];
5445 if (npi.name.equals(perm)
5446 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
5448 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
5456 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
5457 BasePermission bp, HashSet<String> origPermissions) {
5459 allowed = (compareSignatures(
5460 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
5461 == PackageManager.SIGNATURE_MATCH)
5462 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
5463 == PackageManager.SIGNATURE_MATCH);
5464 if (!allowed && (bp.protectionLevel
5465 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
5466 if (isSystemApp(pkg)) {
5467 // For updated system applications, a system permission
5468 // is granted only if it had been defined by the original application.
5469 if (isUpdatedSystemApp(pkg)) {
5470 final PackageSetting sysPs = mSettings
5471 .getDisabledSystemPkgLPr(pkg.packageName);
5472 final GrantedPermissions origGp = sysPs.sharedUser != null
5473 ? sysPs.sharedUser : sysPs;
5474 if (origGp.grantedPermissions.contains(perm)) {
5477 // The system apk may have been updated with an older
5478 // version of the one on the data partition, but which
5479 // granted a new system permission that it didn't have
5480 // before. In this case we do want to allow the app to
5481 // now get the new permission, because it is allowed by
5482 // the system image.
5484 if (sysPs.pkg != null) {
5486 j<sysPs.pkg.requestedPermissions.size(); j++) {
5488 sysPs.pkg.requestedPermissions.get(j))) {
5500 if (!allowed && (bp.protectionLevel
5501 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
5502 // For development permissions, a development permission
5503 // is granted only if it was already granted.
5504 allowed = origPermissions.contains(perm);
5509 final class ActivityIntentResolver
5510 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
5511 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
5512 boolean defaultOnly, int userId) {
5513 if (!sUserManager.exists(userId)) return null;
5514 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
5515 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
5518 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
5520 if (!sUserManager.exists(userId)) return null;
5522 return super.queryIntent(intent, resolvedType,
5523 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
5526 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
5527 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
5528 if (!sUserManager.exists(userId)) return null;
5529 if (packageActivities == null) {
5533 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
5534 final int N = packageActivities.size();
5535 ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
5536 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
5538 ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
5539 for (int i = 0; i < N; ++i) {
5540 intentFilters = packageActivities.get(i).intents;
5541 if (intentFilters != null && intentFilters.size() > 0) {
5542 PackageParser.ActivityIntentInfo[] array =
5543 new PackageParser.ActivityIntentInfo[intentFilters.size()];
5544 intentFilters.toArray(array);
5548 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
5551 public final void addActivity(PackageParser.Activity a, String type) {
5552 final boolean systemApp = isSystemApp(a.info.applicationInfo);
5553 mActivities.put(a.getComponentName(), a);
5554 if (DEBUG_SHOW_INFO)
5556 TAG, " " + type + " " +
5557 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
5558 if (DEBUG_SHOW_INFO)
5559 Log.v(TAG, " Class=" + a.info.name);
5560 final int NI = a.intents.size();
5561 for (int j=0; j<NI; j++) {
5562 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
5563 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
5564 intent.setPriority(0);
5565 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
5566 + a.className + " with priority > 0, forcing to 0");
5568 if (DEBUG_SHOW_INFO) {
5569 Log.v(TAG, " IntentFilter:");
5570 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
5572 if (!intent.debugCheck()) {
5573 Log.w(TAG, "==> For Activity " + a.info.name);
5579 public final void removeActivity(PackageParser.Activity a, String type) {
5580 mActivities.remove(a.getComponentName());
5581 if (DEBUG_SHOW_INFO) {
5582 Log.v(TAG, " " + type + " "
5583 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
5584 : a.info.name) + ":");
5585 Log.v(TAG, " Class=" + a.info.name);
5587 final int NI = a.intents.size();
5588 for (int j=0; j<NI; j++) {
5589 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
5590 if (DEBUG_SHOW_INFO) {
5591 Log.v(TAG, " IntentFilter:");
5592 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
5594 removeFilter(intent);
5599 protected boolean allowFilterResult(
5600 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
5601 ActivityInfo filterAi = filter.activity.info;
5602 for (int i=dest.size()-1; i>=0; i--) {
5603 ActivityInfo destAi = dest.get(i).activityInfo;
5604 if (destAi.name == filterAi.name
5605 && destAi.packageName == filterAi.packageName) {
5613 protected ActivityIntentInfo[] newArray(int size) {
5614 return new ActivityIntentInfo[size];
5618 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
5619 if (!sUserManager.exists(userId)) return true;
5620 PackageParser.Package p = filter.activity.owner;
5622 PackageSetting ps = (PackageSetting)p.mExtras;
5624 // System apps are never considered stopped for purposes of
5625 // filtering, because there may be no way for the user to
5626 // actually re-launch them.
5627 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
5628 && ps.getStopped(userId);
5635 protected boolean isPackageForFilter(String packageName,
5636 PackageParser.ActivityIntentInfo info) {
5637 return packageName.equals(info.activity.owner.packageName);
5641 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
5642 int match, int userId) {
5643 if (!sUserManager.exists(userId)) return null;
5644 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
5647 final PackageParser.Activity activity = info.activity;
5648 if (mSafeMode && (activity.info.applicationInfo.flags
5649 &ApplicationInfo.FLAG_SYSTEM) == 0) {
5652 PackageSetting ps = (PackageSetting) activity.owner.mExtras;
5656 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
5657 ps.readUserState(userId), userId);
5661 final ResolveInfo res = new ResolveInfo();
5662 res.activityInfo = ai;
5663 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
5666 res.priority = info.getPriority();
5667 res.preferredOrder = activity.owner.mPreferredOrder;
5668 //System.out.println("Result: " + res.activityInfo.className +
5669 // " = " + res.priority);
5671 res.isDefault = info.hasDefault;
5672 res.labelRes = info.labelRes;
5673 res.nonLocalizedLabel = info.nonLocalizedLabel;
5674 res.icon = info.icon;
5675 res.system = isSystemApp(res.activityInfo.applicationInfo);
5680 protected void sortResults(List<ResolveInfo> results) {
5681 Collections.sort(results, mResolvePrioritySorter);
5685 protected void dumpFilter(PrintWriter out, String prefix,
5686 PackageParser.ActivityIntentInfo filter) {
5687 out.print(prefix); out.print(
5688 Integer.toHexString(System.identityHashCode(filter.activity)));
5690 out.print(filter.activity.getComponentShortName());
5691 out.print(" filter ");
5692 out.println(Integer.toHexString(System.identityHashCode(filter)));
5695 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
5696 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
5697 // final List<ResolveInfo> retList = Lists.newArrayList();
5698 // while (i.hasNext()) {
5699 // final ResolveInfo resolveInfo = i.next();
5700 // if (isEnabledLP(resolveInfo.activityInfo)) {
5701 // retList.add(resolveInfo);
5707 // Keys are String (activity class name), values are Activity.
5708 private final HashMap<ComponentName, PackageParser.Activity> mActivities
5709 = new HashMap<ComponentName, PackageParser.Activity>();
5713 private final class ServiceIntentResolver
5714 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
5715 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
5716 boolean defaultOnly, int userId) {
5717 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
5718 return super.queryIntent(intent, resolvedType, defaultOnly, userId);
5721 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
5723 if (!sUserManager.exists(userId)) return null;
5725 return super.queryIntent(intent, resolvedType,
5726 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
5729 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
5730 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
5731 if (!sUserManager.exists(userId)) return null;
5732 if (packageServices == null) {
5736 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
5737 final int N = packageServices.size();
5738 ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
5739 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
5741 ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
5742 for (int i = 0; i < N; ++i) {
5743 intentFilters = packageServices.get(i).intents;
5744 if (intentFilters != null && intentFilters.size() > 0) {
5745 PackageParser.ServiceIntentInfo[] array =
5746 new PackageParser.ServiceIntentInfo[intentFilters.size()];
5747 intentFilters.toArray(array);
5751 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
5754 public final void addService(PackageParser.Service s) {
5755 mServices.put(s.getComponentName(), s);
5756 if (DEBUG_SHOW_INFO) {
5758 + (s.info.nonLocalizedLabel != null
5759 ? s.info.nonLocalizedLabel : s.info.name) + ":");
5760 Log.v(TAG, " Class=" + s.info.name);
5762 final int NI = s.intents.size();
5764 for (j=0; j<NI; j++) {
5765 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5766 if (DEBUG_SHOW_INFO) {
5767 Log.v(TAG, " IntentFilter:");
5768 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
5770 if (!intent.debugCheck()) {
5771 Log.w(TAG, "==> For Service " + s.info.name);
5777 public final void removeService(PackageParser.Service s) {
5778 mServices.remove(s.getComponentName());
5779 if (DEBUG_SHOW_INFO) {
5780 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
5781 ? s.info.nonLocalizedLabel : s.info.name) + ":");
5782 Log.v(TAG, " Class=" + s.info.name);
5784 final int NI = s.intents.size();
5786 for (j=0; j<NI; j++) {
5787 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5788 if (DEBUG_SHOW_INFO) {
5789 Log.v(TAG, " IntentFilter:");
5790 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
5792 removeFilter(intent);
5797 protected boolean allowFilterResult(
5798 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
5799 ServiceInfo filterSi = filter.service.info;
5800 for (int i=dest.size()-1; i>=0; i--) {
5801 ServiceInfo destAi = dest.get(i).serviceInfo;
5802 if (destAi.name == filterSi.name
5803 && destAi.packageName == filterSi.packageName) {
5811 protected PackageParser.ServiceIntentInfo[] newArray(int size) {
5812 return new PackageParser.ServiceIntentInfo[size];
5816 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
5817 if (!sUserManager.exists(userId)) return true;
5818 PackageParser.Package p = filter.service.owner;
5820 PackageSetting ps = (PackageSetting)p.mExtras;
5822 // System apps are never considered stopped for purposes of
5823 // filtering, because there may be no way for the user to
5824 // actually re-launch them.
5825 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
5826 && ps.getStopped(userId);
5833 protected boolean isPackageForFilter(String packageName,
5834 PackageParser.ServiceIntentInfo info) {
5835 return packageName.equals(info.service.owner.packageName);
5839 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
5840 int match, int userId) {
5841 if (!sUserManager.exists(userId)) return null;
5842 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
5843 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
5846 final PackageParser.Service service = info.service;
5847 if (mSafeMode && (service.info.applicationInfo.flags
5848 &ApplicationInfo.FLAG_SYSTEM) == 0) {
5851 PackageSetting ps = (PackageSetting) service.owner.mExtras;
5855 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
5856 ps.readUserState(userId), userId);
5860 final ResolveInfo res = new ResolveInfo();
5861 res.serviceInfo = si;
5862 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
5863 res.filter = filter;
5865 res.priority = info.getPriority();
5866 res.preferredOrder = service.owner.mPreferredOrder;
5867 //System.out.println("Result: " + res.activityInfo.className +
5868 // " = " + res.priority);
5870 res.isDefault = info.hasDefault;
5871 res.labelRes = info.labelRes;
5872 res.nonLocalizedLabel = info.nonLocalizedLabel;
5873 res.icon = info.icon;
5874 res.system = isSystemApp(res.serviceInfo.applicationInfo);
5879 protected void sortResults(List<ResolveInfo> results) {
5880 Collections.sort(results, mResolvePrioritySorter);
5884 protected void dumpFilter(PrintWriter out, String prefix,
5885 PackageParser.ServiceIntentInfo filter) {
5886 out.print(prefix); out.print(
5887 Integer.toHexString(System.identityHashCode(filter.service)));
5889 out.print(filter.service.getComponentShortName());
5890 out.print(" filter ");
5891 out.println(Integer.toHexString(System.identityHashCode(filter)));
5894 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
5895 // final Iterator<ResolveInfo> i = resolveInfoList.iterator();
5896 // final List<ResolveInfo> retList = Lists.newArrayList();
5897 // while (i.hasNext()) {
5898 // final ResolveInfo resolveInfo = (ResolveInfo) i;
5899 // if (isEnabledLP(resolveInfo.serviceInfo)) {
5900 // retList.add(resolveInfo);
5906 // Keys are String (activity class name), values are Activity.
5907 private final HashMap<ComponentName, PackageParser.Service> mServices
5908 = new HashMap<ComponentName, PackageParser.Service>();
5912 private static final Comparator<ResolveInfo> mResolvePrioritySorter =
5913 new Comparator<ResolveInfo>() {
5914 public int compare(ResolveInfo r1, ResolveInfo r2) {
5915 int v1 = r1.priority;
5916 int v2 = r2.priority;
5917 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
5919 return (v1 > v2) ? -1 : 1;
5921 v1 = r1.preferredOrder;
5922 v2 = r2.preferredOrder;
5924 return (v1 > v2) ? -1 : 1;
5926 if (r1.isDefault != r2.isDefault) {
5927 return r1.isDefault ? -1 : 1;
5931 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
5933 return (v1 > v2) ? -1 : 1;
5935 if (r1.system != r2.system) {
5936 return r1.system ? -1 : 1;
5942 private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
5943 new Comparator<ProviderInfo>() {
5944 public int compare(ProviderInfo p1, ProviderInfo p2) {
5945 final int v1 = p1.initOrder;
5946 final int v2 = p2.initOrder;
5947 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
5951 static final void sendPackageBroadcast(String action, String pkg,
5952 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
5954 IActivityManager am = ActivityManagerNative.getDefault();
5957 if (userIds == null) {
5958 userIds = am.getRunningUserIds();
5960 for (int id : userIds) {
5961 final Intent intent = new Intent(action,
5962 pkg != null ? Uri.fromParts("package", pkg, null) : null);
5963 if (extras != null) {
5964 intent.putExtras(extras);
5966 if (targetPkg != null) {
5967 intent.setPackage(targetPkg);
5969 // Modify the UID when posting to other users
5970 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
5971 if (uid > 0 && UserHandle.getUserId(uid) != id) {
5972 uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
5973 intent.putExtra(Intent.EXTRA_UID, uid);
5975 intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
5976 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
5977 if (DEBUG_BROADCASTS) {
5978 RuntimeException here = new RuntimeException("here");
5979 here.fillInStackTrace();
5980 Slog.d(TAG, "Sending to user " + id + ": "
5981 + intent.toShortString(false, true, false, false)
5982 + " " + intent.getExtras(), here);
5984 am.broadcastIntent(null, intent, null, finishedReceiver,
5985 0, null, null, null, android.app.AppOpsManager.OP_NONE,
5986 finishedReceiver != null, false, id);
5988 } catch (RemoteException ex) {
5994 * Check if the external storage media is available. This is true if there
5995 * is a mounted external storage medium or if the external storage is
5998 private boolean isExternalMediaAvailable() {
5999 return mMediaMounted || Environment.isExternalStorageEmulated();
6002 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
6004 synchronized (mPackages) {
6005 if (!isExternalMediaAvailable()) {
6006 // If the external storage is no longer mounted at this point,
6007 // the caller may not have been able to delete all of this
6008 // packages files and can not delete any more. Bail.
6011 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
6012 if (lastPackage != null) {
6013 pkgs.remove(lastPackage);
6015 if (pkgs.size() > 0) {
6022 void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
6024 RuntimeException here = new RuntimeException("here");
6025 here.fillInStackTrace();
6026 Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId
6027 + " andCode=" + andCode, here);
6029 mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE,
6030 userId, andCode ? 1 : 0, packageName));
6033 void startCleaningPackages() {
6035 synchronized (mPackages) {
6036 if (!isExternalMediaAvailable()) {
6039 if (mSettings.mPackagesToBeCleaned.isEmpty()) {
6043 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
6044 intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
6045 IActivityManager am = ActivityManagerNative.getDefault();
6048 am.startService(null, intent, null, UserHandle.USER_OWNER);
6049 } catch (RemoteException e) {
6054 private final class AppDirObserver extends FileObserver {
6055 public AppDirObserver(String path, int mask, boolean isrom) {
6061 public void onEvent(int event, String path) {
6062 String removedPackage = null;
6063 int removedAppId = -1;
6064 int[] removedUsers = null;
6065 String addedPackage = null;
6066 int addedAppId = -1;
6067 int[] addedUsers = null;
6069 // TODO post a message to the handler to obtain serial ordering
6070 synchronized (mInstallLock) {
6071 String fullPathStr = null;
6072 File fullPath = null;
6074 fullPath = new File(mRootDir, path);
6075 fullPathStr = fullPath.getPath();
6078 if (DEBUG_APP_DIR_OBSERVER)
6079 Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
6081 if (!isPackageFilename(path)) {
6082 if (DEBUG_APP_DIR_OBSERVER)
6083 Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
6087 // Ignore packages that are being installed or
6088 // have just been installed.
6089 if (ignoreCodePath(fullPathStr)) {
6092 PackageParser.Package p = null;
6093 PackageSetting ps = null;
6095 synchronized (mPackages) {
6096 p = mAppDirs.get(fullPathStr);
6098 ps = mSettings.mPackages.get(p.applicationInfo.packageName);
6100 removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
6102 removedUsers = sUserManager.getUserIds();
6105 addedUsers = sUserManager.getUserIds();
6107 if ((event&REMOVE_EVENTS) != 0) {
6109 if (DEBUG_REMOVE) Slog.d(TAG, "Package disappeared: " + ps);
6110 removePackageLI(ps, true);
6111 removedPackage = ps.name;
6112 removedAppId = ps.appId;
6116 if ((event&ADD_EVENTS) != 0) {
6118 if (DEBUG_INSTALL) Slog.d(TAG, "New file appeared: " + fullPath);
6119 p = scanPackageLI(fullPath,
6120 (mIsRom ? PackageParser.PARSE_IS_SYSTEM
6121 | PackageParser.PARSE_IS_SYSTEM_DIR: 0) |
6122 PackageParser.PARSE_CHATTY |
6123 PackageParser.PARSE_MUST_BE_APK,
6124 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
6125 System.currentTimeMillis(), UserHandle.ALL);
6128 * TODO this seems dangerous as the package may have
6129 * changed since we last acquired the mPackages
6133 synchronized (mPackages) {
6134 updatePermissionsLPw(p.packageName, p,
6135 p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
6137 addedPackage = p.applicationInfo.packageName;
6138 addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
6144 synchronized (mPackages) {
6145 mSettings.writeLPr();
6149 if (removedPackage != null) {
6150 Bundle extras = new Bundle(1);
6151 extras.putInt(Intent.EXTRA_UID, removedAppId);
6152 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
6153 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
6154 extras, null, null, removedUsers);
6156 if (addedPackage != null) {
6157 Bundle extras = new Bundle(1);
6158 extras.putInt(Intent.EXTRA_UID, addedAppId);
6159 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
6160 extras, null, null, addedUsers);
6164 private final String mRootDir;
6165 private final boolean mIsRom;
6168 /* Called when a downloaded package installation has been confirmed by the user */
6169 public void installPackage(
6170 final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
6171 installPackage(packageURI, observer, flags, null);
6174 /* Called when a downloaded package installation has been confirmed by the user */
6175 public void installPackage(
6176 final Uri packageURI, final IPackageInstallObserver observer, final int flags,
6177 final String installerPackageName) {
6178 installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
6183 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
6184 int flags, String installerPackageName, Uri verificationURI,
6185 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
6186 VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
6187 VerificationParams.NO_UID, manifestDigest);
6188 installPackageWithVerificationAndEncryption(packageURI, observer, flags,
6189 installerPackageName, verificationParams, encryptionParams);
6192 public void installPackageWithVerificationAndEncryption(Uri packageURI,
6193 IPackageInstallObserver observer, int flags, String installerPackageName,
6194 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
6195 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
6198 final int uid = Binder.getCallingUid();
6199 if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
6201 observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
6202 } catch (RemoteException re) {
6208 if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
6209 user = UserHandle.ALL;
6211 user = new UserHandle(UserHandle.getUserId(uid));
6214 final int filteredFlags;
6216 if (uid == Process.SHELL_UID || uid == 0) {
6217 if (DEBUG_INSTALL) {
6218 Slog.v(TAG, "Install from ADB");
6220 filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
6222 filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
6225 verificationParams.setInstallerUid(uid);
6227 final Message msg = mHandler.obtainMessage(INIT_COPY);
6228 msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
6229 verificationParams, encryptionParams, user);
6230 mHandler.sendMessage(msg);
6237 public int installExistingPackageAsUser(String packageName, int userId) {
6238 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
6240 PackageSetting pkgSetting;
6241 final int uid = Binder.getCallingUid();
6242 if (UserHandle.getUserId(uid) != userId) {
6243 mContext.enforceCallingPermission(
6244 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6245 "installExistingPackage for user " + userId);
6247 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
6248 return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
6251 long callingId = Binder.clearCallingIdentity();
6253 boolean sendAdded = false;
6254 Bundle extras = new Bundle(1);
6257 synchronized (mPackages) {
6258 pkgSetting = mSettings.mPackages.get(packageName);
6259 if (pkgSetting == null) {
6260 return PackageManager.INSTALL_FAILED_INVALID_URI;
6262 if (!pkgSetting.getInstalled(userId)) {
6263 pkgSetting.setInstalled(true, userId);
6264 mSettings.writePackageRestrictionsLPr(userId);
6265 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
6271 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
6272 packageName, extras, null, null, new int[] {userId});
6274 IActivityManager am = ActivityManagerNative.getDefault();
6275 final boolean isSystem =
6276 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
6277 if (isSystem && am.isUserRunning(userId, false)) {
6278 // The just-installed/enabled app is bundled on the system, so presumed
6279 // to be able to run automatically without needing an explicit launch.
6280 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
6281 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
6282 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
6283 .setPackage(packageName);
6284 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
6285 android.app.AppOpsManager.OP_NONE, false, false, userId);
6287 } catch (RemoteException e) {
6289 Slog.w(TAG, "Unable to bootstrap installed package", e);
6293 Binder.restoreCallingIdentity(callingId);
6296 return PackageManager.INSTALL_SUCCEEDED;
6299 private boolean isUserRestricted(int userId, String restrictionKey) {
6300 Bundle restrictions = sUserManager.getUserRestrictions(userId);
6301 if (restrictions.getBoolean(restrictionKey, false)) {
6302 Log.w(TAG, "User is restricted: " + restrictionKey);
6309 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
6310 mContext.enforceCallingOrSelfPermission(
6311 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
6312 "Only package verification agents can verify applications");
6314 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
6315 final PackageVerificationResponse response = new PackageVerificationResponse(
6316 verificationCode, Binder.getCallingUid());
6319 mHandler.sendMessage(msg);
6323 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
6324 long millisecondsToDelay) {
6325 mContext.enforceCallingOrSelfPermission(
6326 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
6327 "Only package verification agents can extend verification timeouts");
6329 final PackageVerificationState state = mPendingVerification.get(id);
6330 final PackageVerificationResponse response = new PackageVerificationResponse(
6331 verificationCodeAtTimeout, Binder.getCallingUid());
6333 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
6334 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
6336 if (millisecondsToDelay < 0) {
6337 millisecondsToDelay = 0;
6339 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
6340 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
6341 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
6344 if ((state != null) && !state.timeoutExtended()) {
6345 state.extendTimeout();
6347 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
6350 mHandler.sendMessageDelayed(msg, millisecondsToDelay);
6354 private void broadcastPackageVerified(int verificationId, Uri packageUri,
6355 int verificationCode, UserHandle user) {
6356 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
6357 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
6358 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
6359 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
6360 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
6362 mContext.sendBroadcastAsUser(intent, user,
6363 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
6366 private ComponentName matchComponentForVerifier(String packageName,
6367 List<ResolveInfo> receivers) {
6368 ActivityInfo targetReceiver = null;
6370 final int NR = receivers.size();
6371 for (int i = 0; i < NR; i++) {
6372 final ResolveInfo info = receivers.get(i);
6373 if (info.activityInfo == null) {
6377 if (packageName.equals(info.activityInfo.packageName)) {
6378 targetReceiver = info.activityInfo;
6383 if (targetReceiver == null) {
6387 return new ComponentName(targetReceiver.packageName, targetReceiver.name);
6390 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
6391 List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
6392 if (pkgInfo.verifiers.length == 0) {
6396 final int N = pkgInfo.verifiers.length;
6397 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
6398 for (int i = 0; i < N; i++) {
6399 final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
6401 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
6407 final int verifierUid = getUidForVerifier(verifierInfo);
6408 if (verifierUid == -1) {
6413 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
6414 + " with the correct signature");
6416 sufficientVerifiers.add(comp);
6417 verificationState.addSufficientVerifier(verifierUid);
6420 return sufficientVerifiers;
6423 private int getUidForVerifier(VerifierInfo verifierInfo) {
6424 synchronized (mPackages) {
6425 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
6428 } else if (pkg.mSignatures.length != 1) {
6429 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
6430 + " has more than one signature; ignoring");
6435 * If the public key of the package's signature does not match
6436 * our expected public key, then this is a different package and
6440 final byte[] expectedPublicKey;
6442 final Signature verifierSig = pkg.mSignatures[0];
6443 final PublicKey publicKey = verifierSig.getPublicKey();
6444 expectedPublicKey = publicKey.getEncoded();
6445 } catch (CertificateException e) {
6449 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
6451 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
6452 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
6453 + " does not have the expected public key; ignoring");
6457 return pkg.applicationInfo.uid;
6461 public void finishPackageInstall(int token) {
6462 enforceSystemOrRoot("Only the system is allowed to finish installs");
6464 if (DEBUG_INSTALL) {
6465 Slog.v(TAG, "BM finishing package install for " + token);
6468 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
6469 mHandler.sendMessage(msg);
6473 * Get the verification agent timeout.
6475 * @return verification timeout in milliseconds
6477 private long getVerificationTimeout() {
6478 return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
6479 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
6480 DEFAULT_VERIFICATION_TIMEOUT);
6484 * Get the default verification agent response code.
6486 * @return default verification response code
6488 private int getDefaultVerificationResponse() {
6489 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6490 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
6491 DEFAULT_VERIFICATION_RESPONSE);
6495 * Check whether or not package verification has been enabled.
6497 * @return true if verification should be performed
6499 private boolean isVerificationEnabled(int flags) {
6500 if (!DEFAULT_VERIFY_ENABLE) {
6504 // Check if installing from ADB
6505 if ((flags & PackageManager.INSTALL_FROM_ADB) != 0) {
6506 // Do not run verification in a test harness environment
6507 if (ActivityManager.isRunningInTestHarness()) {
6510 // Check if the developer does not want package verification for ADB installs
6511 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6512 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
6517 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6518 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
6522 * Get the "allow unknown sources" setting.
6524 * @return the current "allow unknown sources" setting
6526 private int getUnknownSourcesSettings() {
6527 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6528 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
6532 public void setInstallerPackageName(String targetPackage, String installerPackageName) {
6533 final int uid = Binder.getCallingUid();
6535 synchronized (mPackages) {
6536 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
6537 if (targetPackageSetting == null) {
6538 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
6541 PackageSetting installerPackageSetting;
6542 if (installerPackageName != null) {
6543 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
6544 if (installerPackageSetting == null) {
6545 throw new IllegalArgumentException("Unknown installer package: "
6546 + installerPackageName);
6549 installerPackageSetting = null;
6552 Signature[] callerSignature;
6553 Object obj = mSettings.getUserIdLPr(uid);
6555 if (obj instanceof SharedUserSetting) {
6556 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
6557 } else if (obj instanceof PackageSetting) {
6558 callerSignature = ((PackageSetting)obj).signatures.mSignatures;
6560 throw new SecurityException("Bad object " + obj + " for uid " + uid);
6563 throw new SecurityException("Unknown calling uid " + uid);
6566 // Verify: can't set installerPackageName to a package that is
6567 // not signed with the same cert as the caller.
6568 if (installerPackageSetting != null) {
6569 if (compareSignatures(callerSignature,
6570 installerPackageSetting.signatures.mSignatures)
6571 != PackageManager.SIGNATURE_MATCH) {
6572 throw new SecurityException(
6573 "Caller does not have same cert as new installer package "
6574 + installerPackageName);
6578 // Verify: if target already has an installer package, it must
6579 // be signed with the same cert as the caller.
6580 if (targetPackageSetting.installerPackageName != null) {
6581 PackageSetting setting = mSettings.mPackages.get(
6582 targetPackageSetting.installerPackageName);
6583 // If the currently set package isn't valid, then it's always
6584 // okay to change it.
6585 if (setting != null) {
6586 if (compareSignatures(callerSignature,
6587 setting.signatures.mSignatures)
6588 != PackageManager.SIGNATURE_MATCH) {
6589 throw new SecurityException(
6590 "Caller does not have same cert as old installer package "
6591 + targetPackageSetting.installerPackageName);
6597 targetPackageSetting.installerPackageName = installerPackageName;
6598 scheduleWriteSettingsLocked();
6602 private void processPendingInstall(final InstallArgs args, final int currentStatus) {
6603 // Queue up an async operation since the package installation may take a little while.
6604 mHandler.post(new Runnable() {
6606 mHandler.removeCallbacks(this);
6607 // Result object to be returned
6608 PackageInstalledInfo res = new PackageInstalledInfo();
6609 res.returnCode = currentStatus;
6612 res.removedInfo = new PackageRemovedInfo();
6613 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
6614 args.doPreInstall(res.returnCode);
6615 synchronized (mInstallLock) {
6616 installPackageLI(args, true, res);
6618 args.doPostInstall(res.returnCode, res.uid);
6621 // A restore should be performed at this point if (a) the install
6622 // succeeded, (b) the operation is not an update, and (c) the new
6623 // package has a backupAgent defined.
6624 final boolean update = res.removedInfo.removedPackage != null;
6625 boolean doRestore = (!update
6627 && res.pkg.applicationInfo.backupAgentName != null);
6629 // Set up the post-install work request bookkeeping. This will be used
6630 // and cleaned up by the post-install event handling regardless of whether
6631 // there's a restore pass performed. Token values are >= 1.
6633 if (mNextInstallToken < 0) mNextInstallToken = 1;
6634 token = mNextInstallToken++;
6636 PostInstallData data = new PostInstallData(args, res);
6637 mRunningInstalls.put(token, data);
6638 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
6640 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
6641 // Pass responsibility to the Backup Manager. It will perform a
6642 // restore if appropriate, then pass responsibility back to the
6643 // Package Manager to run the post-install observer callbacks
6645 IBackupManager bm = IBackupManager.Stub.asInterface(
6646 ServiceManager.getService(Context.BACKUP_SERVICE));
6648 if (DEBUG_INSTALL) Log.v(TAG, "token " + token
6649 + " to BM for possible restore");
6651 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
6652 } catch (RemoteException e) {
6653 // can't happen; the backup manager is local
6654 } catch (Exception e) {
6655 Slog.e(TAG, "Exception trying to enqueue restore", e);
6659 Slog.e(TAG, "Backup Manager not found!");
6665 // No restore possible, or the Backup Manager was mysteriously not
6666 // available -- just fire the post-install work request directly.
6667 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
6668 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
6669 mHandler.sendMessage(msg);
6675 private abstract class HandlerParams {
6676 private static final int MAX_RETRIES = 4;
6679 * Number of times startCopy() has been attempted and had a non-fatal
6682 private int mRetries = 0;
6684 /** User handle for the user requesting the information or installation. */
6685 private final UserHandle mUser;
6687 HandlerParams(UserHandle user) {
6691 UserHandle getUser() {
6695 final boolean startCopy() {
6698 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
6700 if (++mRetries > MAX_RETRIES) {
6701 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
6702 mHandler.sendEmptyMessage(MCS_GIVE_UP);
6703 handleServiceError();
6709 } catch (RemoteException e) {
6710 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
6711 mHandler.sendEmptyMessage(MCS_RECONNECT);
6718 final void serviceError() {
6719 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
6720 handleServiceError();
6724 abstract void handleStartCopy() throws RemoteException;
6725 abstract void handleServiceError();
6726 abstract void handleReturnCode();
6729 class MeasureParams extends HandlerParams {
6730 private final PackageStats mStats;
6731 private boolean mSuccess;
6733 private final IPackageStatsObserver mObserver;
6735 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
6736 super(new UserHandle(stats.userHandle));
6737 mObserver = observer;
6742 public String toString() {
6743 return "MeasureParams{"
6744 + Integer.toHexString(System.identityHashCode(this))
6745 + " " + mStats.packageName + "}";
6749 void handleStartCopy() throws RemoteException {
6750 synchronized (mInstallLock) {
6751 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
6754 final boolean mounted;
6755 if (Environment.isExternalStorageEmulated()) {
6758 final String status = Environment.getExternalStorageState();
6759 mounted = (Environment.MEDIA_MOUNTED.equals(status)
6760 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
6764 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
6766 final File externalCacheDir = userEnv
6767 .getExternalStorageAppCacheDirectory(mStats.packageName);
6768 final long externalCacheSize = mContainerService
6769 .calculateDirectorySize(externalCacheDir.getPath());
6770 mStats.externalCacheSize = externalCacheSize;
6772 final File externalDataDir = userEnv
6773 .getExternalStorageAppDataDirectory(mStats.packageName);
6774 long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
6777 if (externalCacheDir.getParentFile().equals(externalDataDir)) {
6778 externalDataSize -= externalCacheSize;
6780 mStats.externalDataSize = externalDataSize;
6782 final File externalMediaDir = userEnv
6783 .getExternalStorageAppMediaDirectory(mStats.packageName);
6784 mStats.externalMediaSize = mContainerService
6785 .calculateDirectorySize(externalMediaDir.getPath());
6787 final File externalObbDir = userEnv
6788 .getExternalStorageAppObbDirectory(mStats.packageName);
6789 mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
6795 void handleReturnCode() {
6796 if (mObserver != null) {
6798 mObserver.onGetStatsCompleted(mStats, mSuccess);
6799 } catch (RemoteException e) {
6800 Slog.i(TAG, "Observer no longer exists.");
6806 void handleServiceError() {
6807 Slog.e(TAG, "Could not measure application " + mStats.packageName
6808 + " external storage");
6812 class InstallParams extends HandlerParams {
6813 final IPackageInstallObserver observer;
6816 private final Uri mPackageURI;
6817 final String installerPackageName;
6818 final VerificationParams verificationParams;
6819 private InstallArgs mArgs;
6821 private File mTempPackage;
6822 final ContainerEncryptionParams encryptionParams;
6824 InstallParams(Uri packageURI,
6825 IPackageInstallObserver observer, int flags,
6826 String installerPackageName, VerificationParams verificationParams,
6827 ContainerEncryptionParams encryptionParams, UserHandle user) {
6829 this.mPackageURI = packageURI;
6831 this.observer = observer;
6832 this.installerPackageName = installerPackageName;
6833 this.verificationParams = verificationParams;
6834 this.encryptionParams = encryptionParams;
6838 public String toString() {
6839 return "InstallParams{"
6840 + Integer.toHexString(System.identityHashCode(this))
6841 + " " + mPackageURI + "}";
6844 public ManifestDigest getManifestDigest() {
6845 if (verificationParams == null) {
6848 return verificationParams.getManifestDigest();
6851 private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
6852 String packageName = pkgLite.packageName;
6853 int installLocation = pkgLite.installLocation;
6854 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
6856 synchronized (mPackages) {
6857 PackageParser.Package pkg = mPackages.get(packageName);
6859 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
6860 // Check for downgrading.
6861 if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
6862 if (pkgLite.versionCode < pkg.mVersionCode) {
6863 Slog.w(TAG, "Can't install update of " + packageName
6864 + " update version " + pkgLite.versionCode
6865 + " is older than installed version "
6866 + pkg.mVersionCode);
6867 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
6870 // Check for updated system application.
6871 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6873 Slog.w(TAG, "Cannot install update to system app on sdcard");
6874 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
6876 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6879 // Install flag overrides everything.
6880 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6882 // If current upgrade specifies particular preference
6883 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
6884 // Application explicitly specified internal.
6885 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6886 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
6887 // App explictly prefers external. Let policy decide
6889 // Prefer previous location
6890 if (isExternal(pkg)) {
6891 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6893 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6897 // Invalid install. Return error code
6898 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
6902 // All the special cases have been taken care of.
6903 // Return result based on recommended install location.
6905 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6907 return pkgLite.recommendedInstallLocation;
6911 * Invoke remote method to get package information and install
6912 * location values. Override install location based on default
6913 * policy if needed and then create install arguments based
6914 * on the install location.
6916 public void handleStartCopy() throws RemoteException {
6917 int ret = PackageManager.INSTALL_SUCCEEDED;
6918 final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
6919 final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
6920 PackageInfoLite pkgLite = null;
6922 if (onInt && onSd) {
6923 // Check if both bits are set.
6924 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
6925 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
6927 final long lowThreshold;
6929 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
6930 .getService(DeviceStorageMonitorService.SERVICE);
6932 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
6935 lowThreshold = dsm.getMemoryLowThreshold();
6939 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI,
6940 Intent.FLAG_GRANT_READ_URI_PERMISSION);
6942 final File packageFile;
6943 if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) {
6944 mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir);
6945 if (mTempPackage != null) {
6946 ParcelFileDescriptor out;
6948 out = ParcelFileDescriptor.open(mTempPackage,
6949 ParcelFileDescriptor.MODE_READ_WRITE);
6950 } catch (FileNotFoundException e) {
6952 Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI);
6955 // Make a temporary file for decryption.
6956 ret = mContainerService
6957 .copyResource(mPackageURI, encryptionParams, out);
6958 IoUtils.closeQuietly(out);
6960 packageFile = mTempPackage;
6962 FileUtils.setPermissions(packageFile.getAbsolutePath(),
6963 FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP
6964 | FileUtils.S_IROTH,
6970 packageFile = new File(mPackageURI.getPath());
6973 if (packageFile != null) {
6974 // Remote call to find out default install location
6975 final String packageFilePath = packageFile.getAbsolutePath();
6976 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags,
6980 * If we have too little free space, try to free cache
6983 if (pkgLite.recommendedInstallLocation
6984 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
6985 final long size = mContainerService.calculateInstalledSize(
6986 packageFilePath, isForwardLocked());
6987 if (mInstaller.freeCache(size + lowThreshold) >= 0) {
6988 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath,
6989 flags, lowThreshold);
6992 * The cache free must have deleted the file we
6993 * downloaded to install.
6995 * TODO: fix the "freeCache" call to not delete
6996 * the file we care about.
6998 if (pkgLite.recommendedInstallLocation
6999 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
7000 pkgLite.recommendedInstallLocation
7001 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
7006 mContext.revokeUriPermission(mPackageURI,
7007 Intent.FLAG_GRANT_READ_URI_PERMISSION);
7011 if (ret == PackageManager.INSTALL_SUCCEEDED) {
7012 int loc = pkgLite.recommendedInstallLocation;
7013 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
7014 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
7015 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
7016 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
7017 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
7018 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7019 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
7020 ret = PackageManager.INSTALL_FAILED_INVALID_APK;
7021 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
7022 ret = PackageManager.INSTALL_FAILED_INVALID_URI;
7023 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
7024 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
7026 // Override with defaults if needed.
7027 loc = installLocationPolicy(pkgLite, flags);
7028 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
7029 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
7030 } else if (!onSd && !onInt) {
7031 // Override install location with flags
7032 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
7033 // Set the flag to install on external media.
7034 flags |= PackageManager.INSTALL_EXTERNAL;
7035 flags &= ~PackageManager.INSTALL_INTERNAL;
7037 // Make sure the flag for installing on external
7039 flags |= PackageManager.INSTALL_INTERNAL;
7040 flags &= ~PackageManager.INSTALL_EXTERNAL;
7046 final InstallArgs args = createInstallArgs(this);
7049 if (ret == PackageManager.INSTALL_SUCCEEDED) {
7051 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
7052 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
7054 int userIdentifier = getUser().getIdentifier();
7055 if (userIdentifier == UserHandle.USER_ALL
7056 && ((flags & PackageManager.INSTALL_FROM_ADB) != 0)) {
7057 userIdentifier = UserHandle.USER_OWNER;
7061 * Determine if we have any installed package verifiers. If we
7062 * do, then we'll defer to them to verify the packages.
7064 final int requiredUid = mRequiredVerifierPackage == null ? -1
7065 : getPackageUid(mRequiredVerifierPackage, userIdentifier);
7066 if (requiredUid != -1 && isVerificationEnabled(flags)) {
7067 final Intent verification = new Intent(
7068 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
7069 verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE);
7070 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
7072 final List<ResolveInfo> receivers = queryIntentReceivers(verification,
7073 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
7074 0 /* TODO: Which userId? */);
7077 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
7078 + verification.toString() + " with " + pkgLite.verifiers.length
7079 + " optional verifiers");
7082 final int verificationId = mPendingVerificationToken++;
7084 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
7086 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
7087 installerPackageName);
7089 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
7091 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
7092 pkgLite.packageName);
7094 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
7095 pkgLite.versionCode);
7097 if (verificationParams != null) {
7098 if (verificationParams.getVerificationURI() != null) {
7099 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
7100 verificationParams.getVerificationURI());
7102 if (verificationParams.getOriginatingURI() != null) {
7103 verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
7104 verificationParams.getOriginatingURI());
7106 if (verificationParams.getReferrer() != null) {
7107 verification.putExtra(Intent.EXTRA_REFERRER,
7108 verificationParams.getReferrer());
7110 if (verificationParams.getOriginatingUid() >= 0) {
7111 verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
7112 verificationParams.getOriginatingUid());
7114 if (verificationParams.getInstallerUid() >= 0) {
7115 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
7116 verificationParams.getInstallerUid());
7120 final PackageVerificationState verificationState = new PackageVerificationState(
7123 mPendingVerification.append(verificationId, verificationState);
7125 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
7126 receivers, verificationState);
7129 * If any sufficient verifiers were listed in the package
7130 * manifest, attempt to ask them.
7132 if (sufficientVerifiers != null) {
7133 final int N = sufficientVerifiers.size();
7135 Slog.i(TAG, "Additional verifiers required, but none installed.");
7136 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
7138 for (int i = 0; i < N; i++) {
7139 final ComponentName verifierComponent = sufficientVerifiers.get(i);
7141 final Intent sufficientIntent = new Intent(verification);
7142 sufficientIntent.setComponent(verifierComponent);
7144 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
7149 final ComponentName requiredVerifierComponent = matchComponentForVerifier(
7150 mRequiredVerifierPackage, receivers);
7151 if (ret == PackageManager.INSTALL_SUCCEEDED
7152 && mRequiredVerifierPackage != null) {
7154 * Send the intent to the required verification agent,
7155 * but only start the verification timeout after the
7156 * target BroadcastReceivers have run.
7158 verification.setComponent(requiredVerifierComponent);
7159 mContext.sendOrderedBroadcastAsUser(verification, getUser(),
7160 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
7161 new BroadcastReceiver() {
7163 public void onReceive(Context context, Intent intent) {
7164 final Message msg = mHandler
7165 .obtainMessage(CHECK_PENDING_VERIFICATION);
7166 msg.arg1 = verificationId;
7167 mHandler.sendMessageDelayed(msg, getVerificationTimeout());
7169 }, null, 0, null, null);
7172 * We don't want the copy to proceed until verification
7173 * succeeds, so null out this field.
7179 * No package verification is enabled, so immediately start
7180 * the remote call to initiate copy using temporary file.
7182 ret = args.copyApk(mContainerService, true);
7190 void handleReturnCode() {
7191 // If mArgs is null, then MCS couldn't be reached. When it
7192 // reconnects, it will try again to install. At that point, this
7194 if (mArgs != null) {
7195 processPendingInstall(mArgs, mRet);
7197 if (mTempPackage != null) {
7198 if (!mTempPackage.delete()) {
7199 Slog.w(TAG, "Couldn't delete temporary file: " +
7200 mTempPackage.getAbsolutePath());
7207 void handleServiceError() {
7208 mArgs = createInstallArgs(this);
7209 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7212 public boolean isForwardLocked() {
7213 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7216 public Uri getPackageUri() {
7217 if (mTempPackage != null) {
7218 return Uri.fromFile(mTempPackage);
7226 * Utility class used in movePackage api.
7227 * srcArgs and targetArgs are not set for invalid flags and make
7228 * sure to do null checks when invoking methods on them.
7229 * We probably want to return ErrorPrams for both failed installs
7232 class MoveParams extends HandlerParams {
7233 final IPackageMoveObserver observer;
7235 final String packageName;
7236 final InstallArgs srcArgs;
7237 final InstallArgs targetArgs;
7241 MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
7242 String packageName, String dataDir, int uid, UserHandle user) {
7244 this.srcArgs = srcArgs;
7245 this.observer = observer;
7247 this.packageName = packageName;
7249 if (srcArgs != null) {
7250 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
7251 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
7258 public String toString() {
7259 return "MoveParams{"
7260 + Integer.toHexString(System.identityHashCode(this))
7261 + " " + packageName + "}";
7264 public void handleStartCopy() throws RemoteException {
7265 mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7266 // Check for storage space on target medium
7267 if (!targetArgs.checkFreeStorage(mContainerService)) {
7268 Log.w(TAG, "Insufficient storage to install");
7272 mRet = srcArgs.doPreCopy();
7273 if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7277 mRet = targetArgs.copyApk(mContainerService, false);
7278 if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7279 srcArgs.doPostCopy(uid);
7283 mRet = srcArgs.doPostCopy(uid);
7284 if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7288 mRet = targetArgs.doPreInstall(mRet);
7289 if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7293 if (DEBUG_SD_INSTALL) {
7294 StringBuilder builder = new StringBuilder();
7295 if (srcArgs != null) {
7296 builder.append("src: ");
7297 builder.append(srcArgs.getCodePath());
7299 if (targetArgs != null) {
7300 builder.append(" target : ");
7301 builder.append(targetArgs.getCodePath());
7303 Log.i(TAG, builder.toString());
7308 void handleReturnCode() {
7309 targetArgs.doPostInstall(mRet, uid);
7310 int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
7311 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
7312 currentStatus = PackageManager.MOVE_SUCCEEDED;
7313 } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
7314 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
7316 processPendingMove(this, currentStatus);
7320 void handleServiceError() {
7321 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7326 * Used during creation of InstallArgs
7328 * @param flags package installation flags
7329 * @return true if should be installed on external storage
7331 private static boolean installOnSd(int flags) {
7332 if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
7335 if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
7342 * Used during creation of InstallArgs
7344 * @param flags package installation flags
7345 * @return true if should be installed as forward locked
7347 private static boolean installForwardLocked(int flags) {
7348 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7351 private InstallArgs createInstallArgs(InstallParams params) {
7352 if (installOnSd(params.flags) || params.isForwardLocked()) {
7353 return new AsecInstallArgs(params);
7355 return new FileInstallArgs(params);
7359 private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
7360 String nativeLibraryPath) {
7361 final boolean isInAsec;
7362 if (installOnSd(flags)) {
7363 /* Apps on SD card are always in ASEC containers. */
7365 } else if (installForwardLocked(flags)
7366 && !fullCodePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
7368 * Forward-locked apps are only in ASEC containers if they're the
7377 return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
7378 installOnSd(flags), installForwardLocked(flags));
7380 return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
7384 // Used by package mover
7385 private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
7386 if (installOnSd(flags) || installForwardLocked(flags)) {
7387 String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
7388 + AsecInstallArgs.RES_FILE_NAME);
7389 return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
7390 installForwardLocked(flags));
7392 return new FileInstallArgs(packageURI, pkgName, dataDir);
7396 static abstract class InstallArgs {
7397 final IPackageInstallObserver observer;
7398 // Always refers to PackageManager flags only
7400 final Uri packageURI;
7401 final String installerPackageName;
7402 final ManifestDigest manifestDigest;
7403 final UserHandle user;
7405 InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
7406 String installerPackageName, ManifestDigest manifestDigest,
7408 this.packageURI = packageURI;
7410 this.observer = observer;
7411 this.installerPackageName = installerPackageName;
7412 this.manifestDigest = manifestDigest;
7416 abstract void createCopyFile();
7417 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
7418 abstract int doPreInstall(int status);
7419 abstract boolean doRename(int status, String pkgName, String oldCodePath);
7421 abstract int doPostInstall(int status, int uid);
7422 abstract String getCodePath();
7423 abstract String getResourcePath();
7424 abstract String getNativeLibraryPath();
7425 // Need installer lock especially for dex file removal.
7426 abstract void cleanUpResourcesLI();
7427 abstract boolean doPostDeleteLI(boolean delete);
7428 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
7431 * Called before the source arguments are copied. This is used mostly
7432 * for MoveParams when it needs to read the source file to put it in the
7436 return PackageManager.INSTALL_SUCCEEDED;
7440 * Called after the source arguments are copied. This is used mostly for
7441 * MoveParams when it needs to read the source file to put it in the
7446 int doPostCopy(int uid) {
7447 return PackageManager.INSTALL_SUCCEEDED;
7450 protected boolean isFwdLocked() {
7451 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7454 UserHandle getUser() {
7459 class FileInstallArgs extends InstallArgs {
7461 String codeFileName;
7462 String resourceFileName;
7464 boolean created = false;
7466 FileInstallArgs(InstallParams params) {
7467 super(params.getPackageUri(), params.observer, params.flags,
7468 params.installerPackageName, params.getManifestDigest(),
7472 FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
7473 super(null, null, 0, null, null, null);
7474 File codeFile = new File(fullCodePath);
7475 installDir = codeFile.getParentFile();
7476 codeFileName = fullCodePath;
7477 resourceFileName = fullResourcePath;
7478 libraryPath = nativeLibraryPath;
7481 FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
7482 super(packageURI, null, 0, null, null, null);
7483 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
7484 String apkName = getNextCodePath(null, pkgName, ".apk");
7485 codeFileName = new File(installDir, apkName + ".apk").getPath();
7486 resourceFileName = getResourcePathFromCodePath();
7487 libraryPath = new File(mAppLibInstallDir, pkgName).getPath();
7490 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
7491 final long lowThreshold;
7493 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
7494 .getService(DeviceStorageMonitorService.SERVICE);
7496 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
7499 if (dsm.isMemoryLow()) {
7500 Log.w(TAG, "Memory is reported as being too low; aborting package install");
7504 lowThreshold = dsm.getMemoryLowThreshold();
7508 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7509 Intent.FLAG_GRANT_READ_URI_PERMISSION);
7510 return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold);
7512 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7516 String getCodePath() {
7517 return codeFileName;
7520 void createCopyFile() {
7521 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
7522 codeFileName = createTempPackageFile(installDir).getPath();
7523 resourceFileName = getResourcePathFromCodePath();
7524 libraryPath = getLibraryPathFromCodePath();
7528 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
7530 // Generate temp file name
7533 // Get a ParcelFileDescriptor to write to the output file
7534 File codeFile = new File(codeFileName);
7537 codeFile.createNewFile();
7539 if (!setPermissions()) {
7540 // Failed setting permissions.
7541 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7543 } catch (IOException e) {
7544 Slog.w(TAG, "Failed to create file " + codeFile);
7545 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7548 ParcelFileDescriptor out = null;
7550 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
7551 } catch (FileNotFoundException e) {
7552 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName);
7553 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7555 // Copy the resource now
7556 int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7558 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7559 Intent.FLAG_GRANT_READ_URI_PERMISSION);
7560 ret = imcs.copyResource(packageURI, null, out);
7562 IoUtils.closeQuietly(out);
7563 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7566 if (isFwdLocked()) {
7567 final File destResourceFile = new File(getResourcePath());
7569 // Copy the public files
7571 PackageHelper.extractPublicFiles(codeFileName, destResourceFile);
7572 } catch (IOException e) {
7573 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a"
7574 + " forward-locked app.");
7575 destResourceFile.delete();
7576 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7580 final File nativeLibraryFile = new File(getNativeLibraryPath());
7581 Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath());
7582 if (nativeLibraryFile.exists()) {
7583 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
7584 nativeLibraryFile.delete();
7587 int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
7588 if (copyRet != PackageManager.INSTALL_SUCCEEDED && copyRet != PackageManager.INSTALL_ABI2_SUCCEEDED) {
7591 } catch (IOException e) {
7592 Slog.e(TAG, "Copying native libraries failed", e);
7593 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7599 int doPreInstall(int status) {
7600 if (status != PackageManager.INSTALL_SUCCEEDED) {
7606 boolean doRename(int status, final String pkgName, String oldCodePath) {
7607 if (status != PackageManager.INSTALL_SUCCEEDED) {
7611 final File oldCodeFile = new File(getCodePath());
7612 final File oldResourceFile = new File(getResourcePath());
7613 final File oldLibraryFile = new File(getNativeLibraryPath());
7615 // Rename APK file based on packageName
7616 final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
7617 final File newCodeFile = new File(installDir, apkName + ".apk");
7618 if (!oldCodeFile.renameTo(newCodeFile)) {
7621 codeFileName = newCodeFile.getPath();
7623 // Rename public resource file if it's forward-locked.
7624 final File newResFile = new File(getResourcePathFromCodePath());
7625 if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
7628 resourceFileName = newResFile.getPath();
7630 // Rename library path
7631 final File newLibraryFile = new File(getLibraryPathFromCodePath());
7632 if (newLibraryFile.exists()) {
7633 NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile);
7634 newLibraryFile.delete();
7636 if (!oldLibraryFile.renameTo(newLibraryFile)) {
7637 Slog.e(TAG, "Cannot rename native library directory "
7638 + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath());
7641 libraryPath = newLibraryFile.getPath();
7643 // Attempt to set permissions
7644 if (!setPermissions()) {
7648 if (!SELinux.restorecon(newCodeFile)) {
7656 int doPostInstall(int status, int uid) {
7657 if (status != PackageManager.INSTALL_SUCCEEDED) {
7663 String getResourcePath() {
7664 return resourceFileName;
7667 private String getResourcePathFromCodePath() {
7668 final String codePath = getCodePath();
7669 if (isFwdLocked()) {
7670 final StringBuilder sb = new StringBuilder();
7672 sb.append(mAppInstallDir.getPath());
7674 sb.append(getApkName(codePath));
7678 * If our APK is a temporary file, mark the resource as a
7679 * temporary file as well so it can be cleaned up after
7680 * catastrophic failure.
7682 if (codePath.endsWith(".tmp")) {
7686 return sb.toString();
7692 private String getLibraryPathFromCodePath() {
7693 return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath();
7697 String getNativeLibraryPath() {
7698 if (libraryPath == null) {
7699 libraryPath = getLibraryPathFromCodePath();
7704 private boolean cleanUp() {
7706 String sourceDir = getCodePath();
7707 String publicSourceDir = getResourcePath();
7708 if (sourceDir != null) {
7709 File sourceFile = new File(sourceDir);
7710 if (!sourceFile.exists()) {
7711 Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
7714 // Delete application's code and resources
7715 sourceFile.delete();
7717 if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
7718 final File publicSourceFile = new File(publicSourceDir);
7719 if (!publicSourceFile.exists()) {
7720 Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
7722 if (publicSourceFile.exists()) {
7723 publicSourceFile.delete();
7727 if (libraryPath != null) {
7728 File nativeLibraryFile = new File(libraryPath);
7729 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
7730 if (!nativeLibraryFile.delete()) {
7731 Slog.w(TAG, "Couldn't delete native library directory " + libraryPath);
7738 void cleanUpResourcesLI() {
7739 String sourceDir = getCodePath();
7741 int retCode = mInstaller.rmdex(sourceDir);
7743 Slog.w(TAG, "Couldn't remove dex file for package: "
7745 + sourceDir + ", retcode=" + retCode);
7746 // we don't consider this to be a failure of the core package deletion
7751 private boolean setPermissions() {
7752 // TODO Do this in a more elegant way later on. for now just a hack
7753 if (!isFwdLocked()) {
7754 final int filePermissions =
7755 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
7757 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
7759 Slog.e(TAG, "Couldn't set new package file permissions for " +
7761 + ". The return code was: " + retCode);
7762 // TODO Define new internal error
7770 boolean doPostDeleteLI(boolean delete) {
7771 // XXX err, shouldn't we respect the delete flag?
7772 cleanUpResourcesLI();
7777 private boolean isAsecExternal(String cid) {
7778 final String asecPath = PackageHelper.getSdFilesystem(cid);
7779 return !asecPath.startsWith(mAsecInternalPath);
7783 * Extract the MountService "container ID" from the full code path of an
7786 static String cidFromCodePath(String fullCodePath) {
7787 int eidx = fullCodePath.lastIndexOf("/");
7788 String subStr1 = fullCodePath.substring(0, eidx);
7789 int sidx = subStr1.lastIndexOf("/");
7790 return subStr1.substring(sidx+1, eidx);
7793 class AsecInstallArgs extends InstallArgs {
7794 static final String RES_FILE_NAME = "pkg.apk";
7795 static final String PUBLIC_RES_FILE_NAME = "res.zip";
7799 String resourcePath;
7802 AsecInstallArgs(InstallParams params) {
7803 super(params.getPackageUri(), params.observer, params.flags,
7804 params.installerPackageName, params.getManifestDigest(),
7808 AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
7809 boolean isExternal, boolean isForwardLocked) {
7810 super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
7811 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
7813 // Extract cid from fullCodePath
7814 int eidx = fullCodePath.lastIndexOf("/");
7815 String subStr1 = fullCodePath.substring(0, eidx);
7816 int sidx = subStr1.lastIndexOf("/");
7817 cid = subStr1.substring(sidx+1, eidx);
7818 setCachePath(subStr1);
7821 AsecInstallArgs(String cid, boolean isForwardLocked) {
7822 super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
7823 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
7826 setCachePath(PackageHelper.getSdDir(cid));
7829 AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
7830 super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
7831 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
7836 void createCopyFile() {
7837 cid = getTempContainerId();
7840 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
7842 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7843 Intent.FLAG_GRANT_READ_URI_PERMISSION);
7844 return imcs.checkExternalFreeStorage(packageURI, isFwdLocked());
7846 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7850 private final boolean isExternal() {
7851 return (flags & PackageManager.INSTALL_EXTERNAL) != 0;
7854 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
7859 * Pre-emptively destroy the container since it's destroyed if
7860 * copying fails due to it existing anyway.
7862 PackageHelper.destroySdDir(cid);
7865 final String newCachePath;
7867 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7868 Intent.FLAG_GRANT_READ_URI_PERMISSION);
7869 newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(),
7870 RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked());
7872 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7875 if (newCachePath != null) {
7876 setCachePath(newCachePath);
7877 return PackageManager.INSTALL_SUCCEEDED;
7879 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7884 String getCodePath() {
7889 String getResourcePath() {
7890 return resourcePath;
7894 String getNativeLibraryPath() {
7898 int doPreInstall(int status) {
7899 if (status != PackageManager.INSTALL_SUCCEEDED) {
7900 // Destroy container
7901 PackageHelper.destroySdDir(cid);
7903 boolean mounted = PackageHelper.isContainerMounted(cid);
7905 String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
7906 Process.SYSTEM_UID);
7907 if (newCachePath != null) {
7908 setCachePath(newCachePath);
7910 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7917 boolean doRename(int status, final String pkgName,
7918 String oldCodePath) {
7919 String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
7920 String newCachePath = null;
7921 if (PackageHelper.isContainerMounted(cid)) {
7922 // Unmount the container
7923 if (!PackageHelper.unMountSdDir(cid)) {
7924 Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
7928 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
7929 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
7930 " which might be stale. Will try to clean up.");
7931 // Clean up the stale container and proceed to recreate.
7932 if (!PackageHelper.destroySdDir(newCacheId)) {
7933 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
7936 // Successfully cleaned up stale container. Try to rename again.
7937 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
7938 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
7939 + " inspite of cleaning it up.");
7943 if (!PackageHelper.isContainerMounted(newCacheId)) {
7944 Slog.w(TAG, "Mounting container " + newCacheId);
7945 newCachePath = PackageHelper.mountSdDir(newCacheId,
7946 getEncryptKey(), Process.SYSTEM_UID);
7948 newCachePath = PackageHelper.getSdDir(newCacheId);
7950 if (newCachePath == null) {
7951 Slog.w(TAG, "Failed to get cache path for " + newCacheId);
7954 Log.i(TAG, "Succesfully renamed " + cid +
7955 " to " + newCacheId +
7956 " at new path: " + newCachePath);
7958 setCachePath(newCachePath);
7962 private void setCachePath(String newCachePath) {
7963 File cachePath = new File(newCachePath);
7964 libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
7965 packagePath = new File(cachePath, RES_FILE_NAME).getPath();
7967 if (isFwdLocked()) {
7968 resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath();
7970 resourcePath = packagePath;
7974 int doPostInstall(int status, int uid) {
7975 if (status != PackageManager.INSTALL_SUCCEEDED) {
7978 final int groupOwner;
7979 final String protectedFile;
7980 if (isFwdLocked()) {
7981 groupOwner = UserHandle.getSharedAppGid(uid);
7982 protectedFile = RES_FILE_NAME;
7985 protectedFile = null;
7988 if (uid < Process.FIRST_APPLICATION_UID
7989 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
7990 Slog.e(TAG, "Failed to finalize " + cid);
7991 PackageHelper.destroySdDir(cid);
7992 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7995 boolean mounted = PackageHelper.isContainerMounted(cid);
7997 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
8003 private void cleanUp() {
8004 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
8006 // Destroy secure container
8007 PackageHelper.destroySdDir(cid);
8010 void cleanUpResourcesLI() {
8011 String sourceFile = getCodePath();
8013 int retCode = mInstaller.rmdex(sourceFile);
8015 Slog.w(TAG, "Couldn't remove dex file for package: "
8017 + sourceFile.toString() + ", retcode=" + retCode);
8018 // we don't consider this to be a failure of the core package deletion
8023 boolean matchContainer(String app) {
8024 if (cid.startsWith(app)) {
8030 String getPackageName() {
8031 return getAsecPackageName(cid);
8034 boolean doPostDeleteLI(boolean delete) {
8035 boolean ret = false;
8036 boolean mounted = PackageHelper.isContainerMounted(cid);
8039 ret = PackageHelper.unMountSdDir(cid);
8041 if (ret && delete) {
8042 cleanUpResourcesLI();
8049 if (isFwdLocked()) {
8050 if (!PackageHelper.fixSdPermissions(cid,
8051 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
8052 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8056 return PackageManager.INSTALL_SUCCEEDED;
8060 int doPostCopy(int uid) {
8061 if (isFwdLocked()) {
8062 if (uid < Process.FIRST_APPLICATION_UID
8063 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
8065 Slog.e(TAG, "Failed to finalize " + cid);
8066 PackageHelper.destroySdDir(cid);
8067 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8071 return PackageManager.INSTALL_SUCCEEDED;
8075 static String getAsecPackageName(String packageCid) {
8076 int idx = packageCid.lastIndexOf("-");
8080 return packageCid.substring(0, idx);
8083 // Utility method used to create code paths based on package name and available index.
8084 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
8087 // Fall back to default value of idx=1 if prefix is not
8088 // part of oldCodePath
8089 if (oldCodePath != null) {
8090 String subStr = oldCodePath;
8091 // Drop the suffix right away
8092 if (subStr.endsWith(suffix)) {
8093 subStr = subStr.substring(0, subStr.length() - suffix.length());
8095 // If oldCodePath already contains prefix find out the
8096 // ending index to either increment or decrement.
8097 int sidx = subStr.lastIndexOf(prefix);
8099 subStr = subStr.substring(sidx + prefix.length());
8100 if (subStr != null) {
8101 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
8102 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
8105 idx = Integer.parseInt(subStr);
8111 } catch(NumberFormatException e) {
8116 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
8117 return prefix + idxStr;
8120 // Utility method used to ignore ADD/REMOVE events
8121 // by directory observer.
8122 private static boolean ignoreCodePath(String fullPathStr) {
8123 String apkName = getApkName(fullPathStr);
8124 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
8125 if (idx != -1 && ((idx+1) < apkName.length())) {
8126 // Make sure the package ends with a numeral
8127 String version = apkName.substring(idx+1);
8129 Integer.parseInt(version);
8131 } catch (NumberFormatException e) {}
8136 // Utility method that returns the relative package path with respect
8137 // to the installation directory. Like say for /data/data/com.test-1.apk
8138 // string com.test-1 is returned.
8139 static String getApkName(String codePath) {
8140 if (codePath == null) {
8143 int sidx = codePath.lastIndexOf("/");
8144 int eidx = codePath.lastIndexOf(".");
8146 eidx = codePath.length();
8147 } else if (eidx == 0) {
8148 Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
8151 return codePath.substring(sidx+1, eidx);
8154 class PackageInstalledInfo {
8157 // The set of users that originally had this package installed.
8159 // The set of users that now have this package installed.
8161 PackageParser.Package pkg;
8163 PackageRemovedInfo removedInfo;
8167 * Install a non-existing package.
8169 private void installNewPackageLI(PackageParser.Package pkg,
8170 int parseFlags, int scanMode, UserHandle user,
8171 String installerPackageName, PackageInstalledInfo res) {
8172 // Remember this for later, in case we need to rollback this install
8173 String pkgName = pkg.packageName;
8175 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
8176 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
8177 synchronized(mPackages) {
8178 if (mSettings.mRenamedPackages.containsKey(pkgName)) {
8179 // A package with the same name is already installed, though
8180 // it has been renamed to an older name. The package we
8181 // are trying to install should be installed as an update to
8182 // the existing one, but that has not been requested, so bail.
8183 Slog.w(TAG, "Attempt to re-install " + pkgName
8184 + " without first uninstalling package running as "
8185 + mSettings.mRenamedPackages.get(pkgName));
8186 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8189 if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
8190 // Don't allow installation over an existing package with the same name.
8191 Slog.w(TAG, "Attempt to re-install " + pkgName
8192 + " without first uninstalling.");
8193 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8197 mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8198 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
8199 System.currentTimeMillis(), user);
8200 if (newPackage == null) {
8201 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8202 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8203 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8206 updateSettingsLI(newPackage,
8207 installerPackageName,
8210 // delete the partially installed application. the data directory will have to be
8211 // restored if it was already existing
8212 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8213 // remove package from internal structures. Note that we want deletePackageX to
8214 // delete the package data and cache directories that it created in
8215 // scanPackageLocked, unless those directories existed before we even tried to
8217 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
8218 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
8219 res.removedInfo, true);
8224 private void replacePackageLI(PackageParser.Package pkg,
8225 int parseFlags, int scanMode, UserHandle user,
8226 String installerPackageName, PackageInstalledInfo res) {
8228 PackageParser.Package oldPackage;
8229 String pkgName = pkg.packageName;
8231 boolean[] perUserInstalled;
8233 // First find the old package info and check signatures
8234 synchronized(mPackages) {
8235 oldPackage = mPackages.get(pkgName);
8236 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
8237 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
8238 != PackageManager.SIGNATURE_MATCH) {
8239 Slog.w(TAG, "New package has a different signature: " + pkgName);
8240 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
8244 // In case of rollback, remember per-user/profile install state
8245 PackageSetting ps = mSettings.mPackages.get(pkgName);
8246 allUsers = sUserManager.getUserIds();
8247 perUserInstalled = new boolean[allUsers.length];
8248 for (int i = 0; i < allUsers.length; i++) {
8249 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
8252 boolean sysPkg = (isSystemApp(oldPackage));
8254 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
8255 user, allUsers, perUserInstalled, installerPackageName, res);
8257 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
8258 user, allUsers, perUserInstalled, installerPackageName, res);
8262 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
8263 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
8264 int[] allUsers, boolean[] perUserInstalled,
8265 String installerPackageName, PackageInstalledInfo res) {
8266 PackageParser.Package newPackage = null;
8267 String pkgName = deletedPackage.packageName;
8268 boolean deletedPkg = true;
8269 boolean updatedSettings = false;
8271 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
8273 long origUpdateTime;
8274 if (pkg.mExtras != null) {
8275 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
8280 // First delete the existing package while retaining the data directory
8281 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
8282 res.removedInfo, true)) {
8283 // If the existing package wasn't successfully deleted
8284 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
8287 // Successfully deleted the old package. Now proceed with re-installation
8288 mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8289 newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
8290 System.currentTimeMillis(), user);
8291 if (newPackage == null) {
8292 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8293 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8294 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8297 updateSettingsLI(newPackage,
8298 installerPackageName,
8299 allUsers, perUserInstalled,
8301 updatedSettings = true;
8305 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8306 // remove package from internal structures. Note that we want deletePackageX to
8307 // delete the package data and cache directories that it created in
8308 // scanPackageLocked, unless those directories existed before we even tried to
8310 if(updatedSettings) {
8311 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
8313 pkgName, null, true, allUsers, perUserInstalled,
8314 PackageManager.DELETE_KEEP_DATA,
8315 res.removedInfo, true);
8317 // Since we failed to install the new package we need to restore the old
8318 // package that we deleted.
8320 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
8321 File restoreFile = new File(deletedPackage.mPath);
8322 // Parse old package
8323 boolean oldOnSd = isExternal(deletedPackage);
8324 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY |
8325 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
8326 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
8327 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
8329 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
8330 origUpdateTime, null) == null) {
8331 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
8334 // Restore of old package succeeded. Update permissions.
8336 synchronized (mPackages) {
8337 updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
8338 UPDATE_PERMISSIONS_ALL);
8339 // can downgrade to reader
8340 mSettings.writeLPr();
8342 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
8347 private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
8348 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
8349 int[] allUsers, boolean[] perUserInstalled,
8350 String installerPackageName, PackageInstalledInfo res) {
8351 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
8352 + ", old=" + deletedPackage);
8353 PackageParser.Package newPackage = null;
8354 boolean updatedSettings = false;
8355 parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
8356 PackageParser.PARSE_IS_SYSTEM;
8357 String packageName = deletedPackage.packageName;
8358 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
8359 if (packageName == null) {
8360 Slog.w(TAG, "Attempt to delete null packageName.");
8363 PackageParser.Package oldPkg;
8364 PackageSetting oldPkgSetting;
8366 synchronized (mPackages) {
8367 oldPkg = mPackages.get(packageName);
8368 oldPkgSetting = mSettings.mPackages.get(packageName);
8369 if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
8370 (oldPkgSetting == null)) {
8371 Slog.w(TAG, "Couldn't find package:"+packageName+" information");
8376 killApplication(packageName, oldPkg.applicationInfo.uid);
8378 res.removedInfo.uid = oldPkg.applicationInfo.uid;
8379 res.removedInfo.removedPackage = packageName;
8380 // Remove existing system package
8381 removePackageLI(oldPkgSetting, true);
8383 synchronized (mPackages) {
8384 if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
8385 // We didn't need to disable the .apk as a current system package,
8386 // which means we are replacing another update that is already
8387 // installed. We need to make sure to delete the older one's .apk.
8388 res.removedInfo.args = createInstallArgs(0,
8389 deletedPackage.applicationInfo.sourceDir,
8390 deletedPackage.applicationInfo.publicSourceDir,
8391 deletedPackage.applicationInfo.nativeLibraryDir);
8393 res.removedInfo.args = null;
8397 // Successfully disabled the old package. Now proceed with re-installation
8398 mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8399 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
8400 newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);
8401 if (newPackage == null) {
8402 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8403 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8404 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8407 if (newPackage.mExtras != null) {
8408 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
8409 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
8410 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
8412 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
8413 updatedSettings = true;
8416 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8417 // Re installation failed. Restore old information
8418 // Remove new pkg information
8419 if (newPackage != null) {
8420 removeInstalledPackageLI(newPackage, true);
8422 // Add back the old system package
8423 scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
8424 // Restore the old system information in Settings
8425 synchronized(mPackages) {
8426 if (updatedSettings) {
8427 mSettings.enableSystemPackageLPw(packageName);
8428 mSettings.setInstallerPackageName(packageName,
8429 oldPkgSetting.installerPackageName);
8431 mSettings.writeLPr();
8436 // Utility method used to move dex files during install.
8437 private int moveDexFilesLI(PackageParser.Package newPackage) {
8439 if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
8440 retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
8444 * If we're in an engineering build, programs are lazily run
8445 * through dexopt. If the .dex file doesn't exist yet, it
8446 * will be created when the program is run next.
8448 Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
8450 Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
8451 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8455 return PackageManager.INSTALL_SUCCEEDED;
8458 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
8459 int[] allUsers, boolean[] perUserInstalled,
8460 PackageInstalledInfo res) {
8461 String pkgName = newPackage.packageName;
8462 synchronized (mPackages) {
8463 //write settings. the installStatus will be incomplete at this stage.
8464 //note that the new package setting would have already been
8465 //added to mPackages. It hasn't been persisted yet.
8466 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
8467 mSettings.writeLPr();
8470 if ((res.returnCode = moveDexFilesLI(newPackage))
8471 != PackageManager.INSTALL_SUCCEEDED) {
8472 // Discontinue if moving dex files failed.
8476 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.mPath);
8478 synchronized (mPackages) {
8479 updatePermissionsLPw(newPackage.packageName, newPackage,
8480 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
8481 ? UPDATE_PERMISSIONS_ALL : 0));
8482 // For system-bundled packages, we assume that installing an upgraded version
8483 // of the package implies that the user actually wants to run that new code,
8484 // so we enable the package.
8485 if (isSystemApp(newPackage)) {
8486 // NB: implicit assumption that system package upgrades apply to all users
8487 if (DEBUG_INSTALL) {
8488 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
8490 PackageSetting ps = mSettings.mPackages.get(pkgName);
8492 if (res.origUsers != null) {
8493 for (int userHandle : res.origUsers) {
8494 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
8495 userHandle, installerPackageName);
8498 // Also convey the prior install/uninstall state
8499 if (allUsers != null && perUserInstalled != null) {
8500 for (int i = 0; i < allUsers.length; i++) {
8501 if (DEBUG_INSTALL) {
8502 Slog.d(TAG, " user " + allUsers[i]
8503 + " => " + perUserInstalled[i]);
8505 ps.setInstalled(perUserInstalled[i], allUsers[i]);
8507 // these install state changes will be persisted in the
8508 // upcoming call to mSettings.writeLPr().
8513 res.uid = newPackage.applicationInfo.uid;
8514 res.pkg = newPackage;
8515 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
8516 mSettings.setInstallerPackageName(pkgName, installerPackageName);
8517 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
8518 //to update install status
8519 mSettings.writeLPr();
8523 private void installPackageLI(InstallArgs args,
8524 boolean newInstall, PackageInstalledInfo res) {
8525 int pFlags = args.flags;
8526 String installerPackageName = args.installerPackageName;
8527 File tmpPackageFile = new File(args.getCodePath());
8528 boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
8529 boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
8530 boolean replace = false;
8531 int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
8532 | (newInstall ? SCAN_NEW_INSTALL : 0);
8533 // Result object to be returned
8534 res.returnCode = PackageManager.INSTALL_SUCCEEDED;
8536 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
8537 // Retrieve PackageSettings and parse package
8538 int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
8539 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
8540 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
8541 PackageParser pp = new PackageParser(tmpPackageFile.getPath());
8542 pp.setSeparateProcesses(mSeparateProcesses);
8543 final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
8544 null, mMetrics, parseFlags);
8546 res.returnCode = pp.getParseError();
8549 String pkgName = res.name = pkg.packageName;
8550 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
8551 if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
8552 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
8556 if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
8557 res.returnCode = pp.getParseError();
8561 /* If the installer passed in a manifest digest, compare it now. */
8562 if (args.manifestDigest != null) {
8563 if (DEBUG_INSTALL) {
8564 final String parsedManifest = pkg.manifestDigest == null ? "null"
8565 : pkg.manifestDigest.toString();
8566 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
8570 if (!args.manifestDigest.equals(pkg.manifestDigest)) {
8571 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
8574 } else if (DEBUG_INSTALL) {
8575 final String parsedManifest = pkg.manifestDigest == null
8576 ? "null" : pkg.manifestDigest.toString();
8577 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
8580 // Get rid of all references to package scan path via parser.
8582 String oldCodePath = null;
8583 boolean systemApp = false;
8584 synchronized (mPackages) {
8585 // Check if installing already existing package
8586 if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
8587 String oldName = mSettings.mRenamedPackages.get(pkgName);
8588 if (pkg.mOriginalPackages != null
8589 && pkg.mOriginalPackages.contains(oldName)
8590 && mPackages.containsKey(oldName)) {
8591 // This package is derived from an original package,
8592 // and this device has been updating from that original
8593 // name. We must continue using the original name, so
8594 // rename the new package here.
8595 pkg.setPackageName(oldName);
8596 pkgName = pkg.packageName;
8598 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
8599 + oldName + " pkgName=" + pkgName);
8600 } else if (mPackages.containsKey(pkgName)) {
8601 // This package, under its official name, already exists
8602 // on the device; we should replace it.
8604 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
8607 PackageSetting ps = mSettings.mPackages.get(pkgName);
8609 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
8610 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
8611 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
8612 systemApp = (ps.pkg.applicationInfo.flags &
8613 ApplicationInfo.FLAG_SYSTEM) != 0;
8615 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
8619 if (systemApp && onSd) {
8620 // Disable updates to system apps on sdcard
8621 Slog.w(TAG, "Cannot install updates to system apps on sdcard");
8622 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8626 if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
8627 res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8630 // Set application objects path explicitly after the rename
8631 setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
8632 pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
8634 replacePackageLI(pkg, parseFlags, scanMode, args.user,
8635 installerPackageName, res);
8637 installNewPackageLI(pkg, parseFlags, scanMode, args.user,
8638 installerPackageName, res);
8640 synchronized (mPackages) {
8641 final PackageSetting ps = mSettings.mPackages.get(pkgName);
8643 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
8648 private static boolean isForwardLocked(PackageParser.Package pkg) {
8649 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
8653 private boolean isForwardLocked(PackageSetting ps) {
8654 return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
8657 private static boolean isExternal(PackageParser.Package pkg) {
8658 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
8661 private static boolean isExternal(PackageSetting ps) {
8662 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
8665 private static boolean isSystemApp(PackageParser.Package pkg) {
8666 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8669 private static boolean isSystemApp(ApplicationInfo info) {
8670 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8673 private static boolean isSystemApp(PackageSetting ps) {
8674 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
8677 private static boolean isUpdatedSystemApp(PackageSetting ps) {
8678 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
8681 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
8682 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
8685 private int packageFlagsToInstallFlags(PackageSetting ps) {
8686 int installFlags = 0;
8687 if (isExternal(ps)) {
8688 installFlags |= PackageManager.INSTALL_EXTERNAL;
8690 if (isForwardLocked(ps)) {
8691 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
8693 return installFlags;
8696 private void deleteTempPackageFiles() {
8697 final FilenameFilter filter = new FilenameFilter() {
8698 public boolean accept(File dir, String name) {
8699 return name.startsWith("vmdl") && name.endsWith(".tmp");
8702 deleteTempPackageFilesInDirectory(mAppInstallDir, filter);
8703 deleteTempPackageFilesInDirectory(mDrmAppPrivateInstallDir, filter);
8706 private static final void deleteTempPackageFilesInDirectory(File directory,
8707 FilenameFilter filter) {
8708 final String[] tmpFilesList = directory.list(filter);
8709 if (tmpFilesList == null) {
8712 for (int i = 0; i < tmpFilesList.length; i++) {
8713 final File tmpFile = new File(directory, tmpFilesList[i]);
8718 private File createTempPackageFile(File installDir) {
8719 File tmpPackageFile;
8721 tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir);
8722 } catch (IOException e) {
8723 Slog.e(TAG, "Couldn't create temp file for downloaded package file.");
8727 FileUtils.setPermissions(
8728 tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
8730 if (!SELinux.restorecon(tmpPackageFile)) {
8733 } catch (IOException e) {
8734 Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
8737 return tmpPackageFile;
8741 public void deletePackageAsUser(final String packageName,
8742 final IPackageDeleteObserver observer,
8743 final int userId, final int flags) {
8744 mContext.enforceCallingOrSelfPermission(
8745 android.Manifest.permission.DELETE_PACKAGES, null);
8746 final int uid = Binder.getCallingUid();
8747 if (UserHandle.getUserId(uid) != userId) {
8748 mContext.enforceCallingPermission(
8749 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8750 "deletePackage for user " + userId);
8752 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
8754 observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED);
8755 } catch (RemoteException re) {
8760 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
8761 // Queue up an async operation since the package deletion may take a little while.
8762 mHandler.post(new Runnable() {
8764 mHandler.removeCallbacks(this);
8765 final int returnCode = deletePackageX(packageName, userId, flags);
8766 if (observer != null) {
8768 observer.packageDeleted(packageName, returnCode);
8769 } catch (RemoteException e) {
8770 Log.i(TAG, "Observer no longer exists.");
8778 * This method is an internal method that could be get invoked either
8779 * to delete an installed package or to clean up a failed installation.
8780 * After deleting an installed package, a broadcast is sent to notify any
8781 * listeners that the package has been installed. For cleaning up a failed
8782 * installation, the broadcast is not necessary since the package's
8783 * installation wouldn't have sent the initial broadcast either
8784 * The key steps in deleting a package are
8785 * deleting the package information in internal structures like mPackages,
8786 * deleting the packages base directories through installd
8787 * updating mSettings to reflect current status
8788 * persisting settings for later use
8789 * sending a broadcast if necessary
8791 private int deletePackageX(String packageName, int userId, int flags) {
8792 final PackageRemovedInfo info = new PackageRemovedInfo();
8795 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
8796 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
8798 if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId)
8799 || dpm.isDeviceOwner(packageName))) {
8800 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
8801 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
8803 } catch (RemoteException e) {
8806 boolean removedForAllUsers = false;
8807 boolean systemUpdate = false;
8809 // for the uninstall-updates case and restricted profiles, remember the per-
8810 // userhandle installed state
8812 boolean[] perUserInstalled;
8813 synchronized (mPackages) {
8814 PackageSetting ps = mSettings.mPackages.get(packageName);
8815 allUsers = sUserManager.getUserIds();
8816 perUserInstalled = new boolean[allUsers.length];
8817 for (int i = 0; i < allUsers.length; i++) {
8818 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
8822 synchronized (mInstallLock) {
8823 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
8824 res = deletePackageLI(packageName,
8825 (flags & PackageManager.DELETE_ALL_USERS) != 0
8826 ? UserHandle.ALL : new UserHandle(userId),
8827 true, allUsers, perUserInstalled,
8828 flags | REMOVE_CHATTY, info, true);
8829 systemUpdate = info.isRemovedPackageSystemUpdate;
8830 if (res && !systemUpdate && mPackages.get(packageName) == null) {
8831 removedForAllUsers = true;
8833 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
8834 + " removedForAllUsers=" + removedForAllUsers);
8838 info.sendBroadcast(true, systemUpdate, removedForAllUsers);
8840 // If the removed package was a system update, the old system package
8841 // was re-enabled; we need to broadcast this information
8843 Bundle extras = new Bundle(1);
8844 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
8845 ? info.removedAppId : info.uid);
8846 extras.putBoolean(Intent.EXTRA_REPLACING, true);
8848 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
8849 extras, null, null, null);
8850 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
8851 extras, null, null, null);
8852 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
8853 null, packageName, null, null);
8857 Runtime.getRuntime().gc();
8858 // Delete the resources here after sending the broadcast to let
8859 // other processes clean up before deleting resources.
8860 if (info.args != null) {
8861 synchronized (mInstallLock) {
8862 info.args.doPostDeleteLI(true);
8866 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
8869 static class PackageRemovedInfo {
8870 String removedPackage;
8872 int removedAppId = -1;
8873 int[] removedUsers = null;
8874 boolean isRemovedPackageSystemUpdate = false;
8875 // Clean up resources deleted packages.
8876 InstallArgs args = null;
8878 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
8879 Bundle extras = new Bundle(1);
8880 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
8881 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
8883 extras.putBoolean(Intent.EXTRA_REPLACING, true);
8885 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
8886 if (removedPackage != null) {
8887 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
8888 extras, null, null, removedUsers);
8889 if (fullRemove && !replacing) {
8890 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
8891 extras, null, null, removedUsers);
8894 if (removedAppId >= 0) {
8895 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
8902 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
8903 * flag is not set, the data directory is removed as well.
8904 * make sure this flag is set for partially installed apps. If not its meaningless to
8905 * delete a partially installed application.
8907 private void removePackageDataLI(PackageSetting ps,
8908 int[] allUserHandles, boolean[] perUserInstalled,
8909 PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
8910 String packageName = ps.name;
8911 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
8912 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
8913 // Retrieve object to delete permissions for shared user later on
8914 final PackageSetting deletedPs;
8916 synchronized (mPackages) {
8917 deletedPs = mSettings.mPackages.get(packageName);
8918 if (outInfo != null) {
8919 outInfo.removedPackage = packageName;
8920 outInfo.removedUsers = deletedPs != null
8921 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
8925 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
8926 removeDataDirsLI(packageName);
8927 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
8930 synchronized (mPackages) {
8931 if (deletedPs != null) {
8932 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
8933 if (outInfo != null) {
8934 outInfo.removedAppId = mSettings.removePackageLPw(packageName);
8936 if (deletedPs != null) {
8937 updatePermissionsLPw(deletedPs.name, null, 0);
8938 if (deletedPs.sharedUser != null) {
8939 // remove permissions associated with package
8940 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
8943 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
8945 // make sure to preserve per-user disabled state if this removal was just
8946 // a downgrade of a system app to the factory package
8947 if (allUserHandles != null && perUserInstalled != null) {
8949 Slog.d(TAG, "Propagating install state across downgrade");
8951 for (int i = 0; i < allUserHandles.length; i++) {
8953 Slog.d(TAG, " user " + allUserHandles[i]
8954 + " => " + perUserInstalled[i]);
8956 ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
8960 // can downgrade to reader
8961 if (writeSettings) {
8962 // Save settings now
8963 mSettings.writeLPr();
8966 if (outInfo != null) {
8967 // A user ID was deleted here. Go through all users and remove it
8969 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
8974 * Tries to delete system package.
8976 private boolean deleteSystemPackageLI(PackageSetting newPs,
8977 int[] allUserHandles, boolean[] perUserInstalled,
8978 int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
8979 final boolean applyUserRestrictions
8980 = (allUserHandles != null) && (perUserInstalled != null);
8981 PackageSetting disabledPs = null;
8982 // Confirm if the system package has been updated
8983 // An updated system app can be deleted. This will also have to restore
8984 // the system pkg from system partition
8986 synchronized (mPackages) {
8987 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
8989 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
8990 + " disabledPs=" + disabledPs);
8991 if (disabledPs == null) {
8992 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
8994 } else if (DEBUG_REMOVE) {
8995 Slog.d(TAG, "Deleting system pkg from data partition");
8998 if (applyUserRestrictions) {
8999 Slog.d(TAG, "Remembering install states:");
9000 for (int i = 0; i < allUserHandles.length; i++) {
9001 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
9005 // Delete the updated package
9006 outInfo.isRemovedPackageSystemUpdate = true;
9007 if (disabledPs.versionCode < newPs.versionCode) {
9008 // Delete data for downgrades
9009 flags &= ~PackageManager.DELETE_KEEP_DATA;
9011 // Preserve data by setting flag
9012 flags |= PackageManager.DELETE_KEEP_DATA;
9014 boolean ret = deleteInstalledPackageLI(newPs, true, flags,
9015 allUserHandles, perUserInstalled, outInfo, writeSettings);
9020 synchronized (mPackages) {
9021 // Reinstate the old system package
9022 mSettings.enableSystemPackageLPw(newPs.name);
9023 // Remove any native libraries from the upgraded package.
9024 NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString);
9026 // Install the system package
9027 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
9028 PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath,
9029 PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
9030 SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
9032 if (newPkg == null) {
9033 Slog.w(TAG, "Failed to restore system package:" + newPs.name
9034 + " with error:" + mLastScanError);
9038 synchronized (mPackages) {
9039 updatePermissionsLPw(newPkg.packageName, newPkg,
9040 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
9041 if (applyUserRestrictions) {
9043 Slog.d(TAG, "Propagating install state across reinstall");
9045 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
9046 for (int i = 0; i < allUserHandles.length; i++) {
9048 Slog.d(TAG, " user " + allUserHandles[i]
9049 + " => " + perUserInstalled[i]);
9051 ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
9053 // Regardless of writeSettings we need to ensure that this restriction
9054 // state propagation is persisted
9055 mSettings.writeAllUsersPackageRestrictionsLPr();
9057 // can downgrade to reader here
9058 if (writeSettings) {
9059 mSettings.writeLPr();
9065 private boolean deleteInstalledPackageLI(PackageSetting ps,
9066 boolean deleteCodeAndResources, int flags,
9067 int[] allUserHandles, boolean[] perUserInstalled,
9068 PackageRemovedInfo outInfo, boolean writeSettings) {
9069 if (outInfo != null) {
9070 outInfo.uid = ps.appId;
9073 // Delete package data from internal structures and also remove data if flag is set
9074 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
9076 // Delete application code and resources
9077 if (deleteCodeAndResources && (outInfo != null)) {
9078 outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
9079 ps.resourcePathString, ps.nativeLibraryPathString);
9085 * This method handles package deletion in general
9087 private boolean deletePackageLI(String packageName, UserHandle user,
9088 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
9089 int flags, PackageRemovedInfo outInfo,
9090 boolean writeSettings) {
9091 if (packageName == null) {
9092 Slog.w(TAG, "Attempt to delete null packageName.");
9095 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
9097 boolean dataOnly = false;
9098 int removeUser = -1;
9100 synchronized (mPackages) {
9101 ps = mSettings.mPackages.get(packageName);
9103 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9106 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
9107 && user.getIdentifier() != UserHandle.USER_ALL) {
9108 // The caller is asking that the package only be deleted for a single
9109 // user. To do this, we just mark its uninstalled state and delete
9110 // its data. If this is a system app, we only allow this to happen if
9111 // they have set the special DELETE_SYSTEM_APP which requests different
9112 // semantics than normal for uninstalling system apps.
9113 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
9114 ps.setUserState(user.getIdentifier(),
9115 COMPONENT_ENABLED_STATE_DEFAULT,
9120 if (!isSystemApp(ps)) {
9121 if (ps.isAnyInstalled(sUserManager.getUserIds())) {
9122 // Other user still have this package installed, so all
9123 // we need to do is clear this user's data and save that
9124 // it is uninstalled.
9125 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
9126 removeUser = user.getIdentifier();
9128 mSettings.writePackageRestrictionsLPr(removeUser);
9130 // We need to set it back to 'installed' so the uninstall
9131 // broadcasts will be sent correctly.
9132 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
9133 ps.setInstalled(true, user.getIdentifier());
9136 // This is a system app, so we assume that the
9137 // other users still have this package installed, so all
9138 // we need to do is clear this user's data and save that
9139 // it is uninstalled.
9140 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
9141 removeUser = user.getIdentifier();
9143 mSettings.writePackageRestrictionsLPr(removeUser);
9148 if (removeUser >= 0) {
9149 // From above, we determined that we are deleting this only
9150 // for a single user. Continue the work here.
9151 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
9152 if (outInfo != null) {
9153 outInfo.removedPackage = packageName;
9154 outInfo.removedAppId = appId;
9155 outInfo.removedUsers = new int[] {removeUser};
9157 mInstaller.clearUserData(packageName, removeUser);
9158 removeKeystoreDataIfNeeded(removeUser, appId);
9159 schedulePackageCleaning(packageName, removeUser, false);
9164 // Delete application data first
9165 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
9166 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
9169 boolean ret = false;
9170 if (isSystemApp(ps)) {
9171 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
9172 // When an updated system application is deleted we delete the existing resources as well and
9173 // fall back to existing code in system partition
9174 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
9175 flags, outInfo, writeSettings);
9177 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
9178 // Kill application pre-emptively especially for apps on sd.
9179 killApplication(packageName, ps.appId);
9180 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
9181 allUserHandles, perUserInstalled,
9182 outInfo, writeSettings);
9187 private final class ClearStorageConnection implements ServiceConnection {
9188 IMediaContainerService mContainerService;
9191 public void onServiceConnected(ComponentName name, IBinder service) {
9192 synchronized (this) {
9193 mContainerService = IMediaContainerService.Stub.asInterface(service);
9199 public void onServiceDisconnected(ComponentName name) {
9203 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
9204 final boolean mounted;
9205 if (Environment.isExternalStorageEmulated()) {
9208 final String status = Environment.getExternalStorageState();
9210 mounted = status.equals(Environment.MEDIA_MOUNTED)
9211 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
9218 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
9220 if (userId == UserHandle.USER_ALL) {
9221 users = sUserManager.getUserIds();
9223 users = new int[] { userId };
9225 final ClearStorageConnection conn = new ClearStorageConnection();
9226 if (mContext.bindServiceAsUser(
9227 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
9229 for (int curUser : users) {
9230 long timeout = SystemClock.uptimeMillis() + 5000;
9231 synchronized (conn) {
9232 long now = SystemClock.uptimeMillis();
9233 while (conn.mContainerService == null && now < timeout) {
9235 conn.wait(timeout - now);
9236 } catch (InterruptedException e) {
9240 if (conn.mContainerService == null) {
9244 final UserEnvironment userEnv = new UserEnvironment(curUser);
9245 final File externalCacheDir = userEnv
9246 .getExternalStorageAppCacheDirectory(packageName);
9248 conn.mContainerService.clearDirectory(externalCacheDir.toString());
9249 } catch (RemoteException e) {
9252 final File externalDataDir = userEnv
9253 .getExternalStorageAppDataDirectory(packageName);
9255 conn.mContainerService.clearDirectory(externalDataDir.toString());
9256 } catch (RemoteException e) {
9258 final File externalMediaDir = userEnv
9259 .getExternalStorageAppMediaDirectory(packageName);
9261 conn.mContainerService.clearDirectory(externalMediaDir.toString());
9262 } catch (RemoteException e) {
9267 mContext.unbindService(conn);
9273 public void clearApplicationUserData(final String packageName,
9274 final IPackageDataObserver observer, final int userId) {
9275 mContext.enforceCallingOrSelfPermission(
9276 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
9277 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
9278 // Queue up an async operation since the package deletion may take a little while.
9279 mHandler.post(new Runnable() {
9281 mHandler.removeCallbacks(this);
9282 final boolean succeeded;
9283 synchronized (mInstallLock) {
9284 succeeded = clearApplicationUserDataLI(packageName, userId);
9286 clearExternalStorageDataSync(packageName, userId, true);
9288 // invoke DeviceStorageMonitor's update method to clear any notifications
9289 DeviceStorageMonitorService dsm = (DeviceStorageMonitorService)
9290 ServiceManager.getService(DeviceStorageMonitorService.SERVICE);
9295 if(observer != null) {
9297 observer.onRemoveCompleted(packageName, succeeded);
9298 } catch (RemoteException e) {
9299 Log.i(TAG, "Observer no longer exists.");
9306 private boolean clearApplicationUserDataLI(String packageName, int userId) {
9307 if (packageName == null) {
9308 Slog.w(TAG, "Attempt to delete null packageName.");
9311 PackageParser.Package p;
9312 boolean dataOnly = false;
9314 synchronized (mPackages) {
9315 p = mPackages.get(packageName);
9318 PackageSetting ps = mSettings.mPackages.get(packageName);
9319 if ((ps == null) || (ps.pkg == null)) {
9320 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9326 // need to check this only for fully installed applications
9328 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9331 final ApplicationInfo applicationInfo = p.applicationInfo;
9332 if (applicationInfo == null) {
9333 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9337 if (p != null && p.applicationInfo != null) {
9338 appId = p.applicationInfo.uid;
9343 int retCode = mInstaller.clearUserData(packageName, userId);
9345 Slog.w(TAG, "Couldn't remove cache files for package: "
9349 removeKeystoreDataIfNeeded(userId, appId);
9354 * Remove entries from the keystore daemon. Will only remove it if the
9355 * {@code appId} is valid.
9357 private static void removeKeystoreDataIfNeeded(int userId, int appId) {
9362 final KeyStore keyStore = KeyStore.getInstance();
9363 if (keyStore != null) {
9364 if (userId == UserHandle.USER_ALL) {
9365 for (final int individual : sUserManager.getUserIds()) {
9366 keyStore.clearUid(UserHandle.getUid(individual, appId));
9369 keyStore.clearUid(UserHandle.getUid(userId, appId));
9372 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
9376 public void deleteApplicationCacheFiles(final String packageName,
9377 final IPackageDataObserver observer) {
9378 mContext.enforceCallingOrSelfPermission(
9379 android.Manifest.permission.DELETE_CACHE_FILES, null);
9380 // Queue up an async operation since the package deletion may take a little while.
9381 final int userId = UserHandle.getCallingUserId();
9382 mHandler.post(new Runnable() {
9384 mHandler.removeCallbacks(this);
9385 final boolean succeded;
9386 synchronized (mInstallLock) {
9387 succeded = deleteApplicationCacheFilesLI(packageName, userId);
9389 clearExternalStorageDataSync(packageName, userId, false);
9390 if(observer != null) {
9392 observer.onRemoveCompleted(packageName, succeded);
9393 } catch (RemoteException e) {
9394 Log.i(TAG, "Observer no longer exists.");
9401 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
9402 if (packageName == null) {
9403 Slog.w(TAG, "Attempt to delete null packageName.");
9406 PackageParser.Package p;
9407 synchronized (mPackages) {
9408 p = mPackages.get(packageName);
9411 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
9414 final ApplicationInfo applicationInfo = p.applicationInfo;
9415 if (applicationInfo == null) {
9416 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9419 int retCode = mInstaller.deleteCacheFiles(packageName, userId);
9421 Slog.w(TAG, "Couldn't remove cache files for package: "
9422 + packageName + " u" + userId);
9428 public void getPackageSizeInfo(final String packageName, int userHandle,
9429 final IPackageStatsObserver observer) {
9430 mContext.enforceCallingOrSelfPermission(
9431 android.Manifest.permission.GET_PACKAGE_SIZE, null);
9433 PackageStats stats = new PackageStats(packageName, userHandle);
9436 * Queue up an async operation since the package measurement may take a
9439 Message msg = mHandler.obtainMessage(INIT_COPY);
9440 msg.obj = new MeasureParams(stats, observer);
9441 mHandler.sendMessage(msg);
9444 private boolean getPackageSizeInfoLI(String packageName, int userHandle,
9445 PackageStats pStats) {
9446 if (packageName == null) {
9447 Slog.w(TAG, "Attempt to get size of null packageName.");
9450 PackageParser.Package p;
9451 boolean dataOnly = false;
9452 String libDirPath = null;
9453 String asecPath = null;
9454 synchronized (mPackages) {
9455 p = mPackages.get(packageName);
9456 PackageSetting ps = mSettings.mPackages.get(packageName);
9459 if((ps == null) || (ps.pkg == null)) {
9460 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
9466 libDirPath = ps.nativeLibraryPathString;
9468 if (p != null && (isExternal(p) || isForwardLocked(p))) {
9469 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir);
9470 if (secureContainerId != null) {
9471 asecPath = PackageHelper.getSdFilesystem(secureContainerId);
9475 String publicSrcDir = null;
9477 final ApplicationInfo applicationInfo = p.applicationInfo;
9478 if (applicationInfo == null) {
9479 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9482 if (isForwardLocked(p)) {
9483 publicSrcDir = applicationInfo.publicSourceDir;
9486 int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath,
9487 publicSrcDir, asecPath, pStats);
9492 // Fix-up for forward-locked applications in ASEC containers.
9493 if (!isExternal(p)) {
9494 pStats.codeSize += pStats.externalCodeSize;
9495 pStats.externalCodeSize = 0L;
9502 public void addPackageToPreferred(String packageName) {
9503 Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
9506 public void removePackageFromPreferred(String packageName) {
9507 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
9510 public List<PackageInfo> getPreferredPackages(int flags) {
9511 return new ArrayList<PackageInfo>();
9514 private int getUidTargetSdkVersionLockedLPr(int uid) {
9515 Object obj = mSettings.getUserIdLPr(uid);
9516 if (obj instanceof SharedUserSetting) {
9517 final SharedUserSetting sus = (SharedUserSetting) obj;
9518 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
9519 final Iterator<PackageSetting> it = sus.packages.iterator();
9520 while (it.hasNext()) {
9521 final PackageSetting ps = it.next();
9522 if (ps.pkg != null) {
9523 int v = ps.pkg.applicationInfo.targetSdkVersion;
9524 if (v < vers) vers = v;
9528 } else if (obj instanceof PackageSetting) {
9529 final PackageSetting ps = (PackageSetting) obj;
9530 if (ps.pkg != null) {
9531 return ps.pkg.applicationInfo.targetSdkVersion;
9534 return Build.VERSION_CODES.CUR_DEVELOPMENT;
9537 public void addPreferredActivity(IntentFilter filter, int match,
9538 ComponentName[] set, ComponentName activity, int userId) {
9540 int callingUid = Binder.getCallingUid();
9541 enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
9542 synchronized (mPackages) {
9543 if (mContext.checkCallingOrSelfPermission(
9544 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
9545 != PackageManager.PERMISSION_GRANTED) {
9546 if (getUidTargetSdkVersionLockedLPr(callingUid)
9547 < Build.VERSION_CODES.FROYO) {
9548 Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
9552 mContext.enforceCallingOrSelfPermission(
9553 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9556 Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
9557 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
9558 mSettings.editPreferredActivitiesLPw(userId).addFilter(
9559 new PreferredActivity(filter, match, set, activity));
9560 mSettings.writePackageRestrictionsLPr(userId);
9564 public void replacePreferredActivity(IntentFilter filter, int match,
9565 ComponentName[] set, ComponentName activity) {
9566 if (filter.countActions() != 1) {
9567 throw new IllegalArgumentException(
9568 "replacePreferredActivity expects filter to have only 1 action.");
9570 if (filter.countCategories() != 1) {
9571 throw new IllegalArgumentException(
9572 "replacePreferredActivity expects filter to have only 1 category.");
9574 if (filter.countDataAuthorities() != 0
9575 || filter.countDataPaths() != 0
9576 || filter.countDataSchemes() != 0
9577 || filter.countDataTypes() != 0) {
9578 throw new IllegalArgumentException(
9579 "replacePreferredActivity expects filter to have no data authorities, " +
9580 "paths, schemes or types.");
9582 synchronized (mPackages) {
9583 if (mContext.checkCallingOrSelfPermission(
9584 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
9585 != PackageManager.PERMISSION_GRANTED) {
9586 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
9587 < Build.VERSION_CODES.FROYO) {
9588 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
9589 + Binder.getCallingUid());
9592 mContext.enforceCallingOrSelfPermission(
9593 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9596 final int callingUserId = UserHandle.getCallingUserId();
9597 ArrayList<PreferredActivity> removed = null;
9598 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
9600 Iterator<PreferredActivity> it = pir.filterIterator();
9601 String action = filter.getAction(0);
9602 String category = filter.getCategory(0);
9603 while (it.hasNext()) {
9604 PreferredActivity pa = it.next();
9605 if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
9606 if (removed == null) {
9607 removed = new ArrayList<PreferredActivity>();
9610 Log.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
9611 filter.dump(new LogPrinter(Log.INFO, TAG), " ");
9614 if (removed != null) {
9615 for (int i=0; i<removed.size(); i++) {
9616 PreferredActivity pa = removed.get(i);
9617 pir.removeFilter(pa);
9621 addPreferredActivity(filter, match, set, activity, callingUserId);
9625 public void clearPackagePreferredActivities(String packageName) {
9626 final int uid = Binder.getCallingUid();
9628 synchronized (mPackages) {
9629 PackageParser.Package pkg = mPackages.get(packageName);
9630 if (pkg == null || pkg.applicationInfo.uid != uid) {
9631 if (mContext.checkCallingOrSelfPermission(
9632 android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
9633 != PackageManager.PERMISSION_GRANTED) {
9634 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
9635 < Build.VERSION_CODES.FROYO) {
9636 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
9637 + Binder.getCallingUid());
9640 mContext.enforceCallingOrSelfPermission(
9641 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9645 int user = UserHandle.getCallingUserId();
9646 if (clearPackagePreferredActivitiesLPw(packageName, user)) {
9647 mSettings.writePackageRestrictionsLPr(user);
9648 scheduleWriteSettingsLocked();
9653 /** This method takes a specific user id as well as UserHandle.USER_ALL. */
9654 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
9655 ArrayList<PreferredActivity> removed = null;
9656 boolean changed = false;
9657 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
9658 final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
9659 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
9660 if (userId != UserHandle.USER_ALL && userId != thisUserId) {
9663 Iterator<PreferredActivity> it = pir.filterIterator();
9664 while (it.hasNext()) {
9665 PreferredActivity pa = it.next();
9666 if (packageName == null ||
9667 pa.mPref.mComponent.getPackageName().equals(packageName)) {
9668 if (removed == null) {
9669 removed = new ArrayList<PreferredActivity>();
9674 if (removed != null) {
9675 for (int j=0; j<removed.size(); j++) {
9676 PreferredActivity pa = removed.get(j);
9677 pir.removeFilter(pa);
9685 public void resetPreferredActivities(int userId) {
9686 mContext.enforceCallingOrSelfPermission(
9687 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9689 synchronized (mPackages) {
9690 int user = UserHandle.getCallingUserId();
9691 clearPackagePreferredActivitiesLPw(null, user);
9692 mSettings.readDefaultPreferredAppsLPw(this, user);
9693 mSettings.writePackageRestrictionsLPr(user);
9694 scheduleWriteSettingsLocked();
9698 public int getPreferredActivities(List<IntentFilter> outFilters,
9699 List<ComponentName> outActivities, String packageName) {
9702 final int userId = UserHandle.getCallingUserId();
9704 synchronized (mPackages) {
9705 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
9707 final Iterator<PreferredActivity> it = pir.filterIterator();
9708 while (it.hasNext()) {
9709 final PreferredActivity pa = it.next();
9710 if (packageName == null
9711 || pa.mPref.mComponent.getPackageName().equals(packageName)) {
9712 if (outFilters != null) {
9713 outFilters.add(new IntentFilter(pa));
9715 if (outActivities != null) {
9716 outActivities.add(pa.mPref.mComponent);
9727 public void setApplicationEnabledSetting(String appPackageName,
9728 int newState, int flags, int userId, String callingPackage) {
9729 if (!sUserManager.exists(userId)) return;
9730 if (callingPackage == null) {
9731 callingPackage = Integer.toString(Binder.getCallingUid());
9733 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
9737 public void setComponentEnabledSetting(ComponentName componentName,
9738 int newState, int flags, int userId) {
9739 if (!sUserManager.exists(userId)) return;
9740 setEnabledSetting(componentName.getPackageName(),
9741 componentName.getClassName(), newState, flags, userId, null);
9744 private void setEnabledSetting(final String packageName, String className, int newState,
9745 final int flags, int userId, String callingPackage) {
9746 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
9747 || newState == COMPONENT_ENABLED_STATE_ENABLED
9748 || newState == COMPONENT_ENABLED_STATE_DISABLED
9749 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
9750 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
9751 throw new IllegalArgumentException("Invalid new component state: "
9754 PackageSetting pkgSetting;
9755 final int uid = Binder.getCallingUid();
9756 final int permission = mContext.checkCallingOrSelfPermission(
9757 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
9758 enforceCrossUserPermission(uid, userId, false, "set enabled");
9759 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
9760 boolean sendNow = false;
9761 boolean isApp = (className == null);
9762 String componentName = isApp ? packageName : className;
9763 int packageUid = -1;
9764 ArrayList<String> components;
9767 synchronized (mPackages) {
9768 pkgSetting = mSettings.mPackages.get(packageName);
9769 if (pkgSetting == null) {
9770 if (className == null) {
9771 throw new IllegalArgumentException(
9772 "Unknown package: " + packageName);
9774 throw new IllegalArgumentException(
9775 "Unknown component: " + packageName
9778 // Allow root and verify that userId is not being specified by a different user
9779 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
9780 throw new SecurityException(
9781 "Permission Denial: attempt to change component state from pid="
9782 + Binder.getCallingPid()
9783 + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
9785 if (className == null) {
9786 // We're dealing with an application/package level state change
9787 if (pkgSetting.getEnabled(userId) == newState) {
9791 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
9792 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
9793 // Don't care about who enables an app.
9794 callingPackage = null;
9796 pkgSetting.setEnabled(newState, userId, callingPackage);
9797 // pkgSetting.pkg.mSetEnabled = newState;
9799 // We're dealing with a component level state change
9800 // First, verify that this is a valid class name.
9801 PackageParser.Package pkg = pkgSetting.pkg;
9802 if (pkg == null || !pkg.hasComponentClassName(className)) {
9803 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
9804 throw new IllegalArgumentException("Component class " + className
9805 + " does not exist in " + packageName);
9807 Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
9808 + className + " does not exist in " + packageName);
9812 case COMPONENT_ENABLED_STATE_ENABLED:
9813 if (!pkgSetting.enableComponentLPw(className, userId)) {
9817 case COMPONENT_ENABLED_STATE_DISABLED:
9818 if (!pkgSetting.disableComponentLPw(className, userId)) {
9822 case COMPONENT_ENABLED_STATE_DEFAULT:
9823 if (!pkgSetting.restoreComponentLPw(className, userId)) {
9828 Slog.e(TAG, "Invalid new component state: " + newState);
9832 mSettings.writePackageRestrictionsLPr(userId);
9833 components = mPendingBroadcasts.get(userId, packageName);
9834 final boolean newPackage = components == null;
9836 components = new ArrayList<String>();
9838 if (!components.contains(componentName)) {
9839 components.add(componentName);
9841 if ((flags&PackageManager.DONT_KILL_APP) == 0) {
9843 // Purge entry from pending broadcast list if another one exists already
9844 // since we are sending one right away.
9845 mPendingBroadcasts.remove(userId, packageName);
9848 mPendingBroadcasts.put(userId, packageName, components);
9850 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
9851 // Schedule a message
9852 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
9857 long callingId = Binder.clearCallingIdentity();
9860 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
9861 sendPackageChangedBroadcast(packageName,
9862 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
9865 Binder.restoreCallingIdentity(callingId);
9869 private void sendPackageChangedBroadcast(String packageName,
9870 boolean killFlag, ArrayList<String> componentNames, int packageUid) {
9872 Log.v(TAG, "Sending package changed: package=" + packageName + " components="
9874 Bundle extras = new Bundle(4);
9875 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
9876 String nameList[] = new String[componentNames.size()];
9877 componentNames.toArray(nameList);
9878 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
9879 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
9880 extras.putInt(Intent.EXTRA_UID, packageUid);
9881 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null,
9882 new int[] {UserHandle.getUserId(packageUid)});
9885 public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
9886 if (!sUserManager.exists(userId)) return;
9887 final int uid = Binder.getCallingUid();
9888 final int permission = mContext.checkCallingOrSelfPermission(
9889 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
9890 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
9891 enforceCrossUserPermission(uid, userId, true, "stop package");
9893 synchronized (mPackages) {
9894 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
9896 scheduleWritePackageRestrictionsLocked(userId);
9901 public String getInstallerPackageName(String packageName) {
9903 synchronized (mPackages) {
9904 return mSettings.getInstallerPackageNameLPr(packageName);
9909 public int getApplicationEnabledSetting(String packageName, int userId) {
9910 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
9911 int uid = Binder.getCallingUid();
9912 enforceCrossUserPermission(uid, userId, false, "get enabled");
9914 synchronized (mPackages) {
9915 return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
9920 public int getComponentEnabledSetting(ComponentName componentName, int userId) {
9921 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
9922 int uid = Binder.getCallingUid();
9923 enforceCrossUserPermission(uid, userId, false, "get component enabled");
9925 synchronized (mPackages) {
9926 return mSettings.getComponentEnabledSettingLPr(componentName, userId);
9930 public void enterSafeMode() {
9931 enforceSystemOrRoot("Only the system can request entering safe mode");
9933 if (!mSystemReady) {
9938 public void systemReady() {
9939 mSystemReady = true;
9941 // Read the compatibilty setting when the system is ready.
9942 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
9943 mContext.getContentResolver(),
9944 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
9945 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
9946 if (DEBUG_SETTINGS) {
9947 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
9950 synchronized (mPackages) {
9951 // Verify that all of the preferred activity components actually
9952 // exist. It is possible for applications to be updated and at
9953 // that point remove a previously declared activity component that
9954 // had been set as a preferred activity. We try to clean this up
9955 // the next time we encounter that preferred activity, but it is
9956 // possible for the user flow to never be able to return to that
9957 // situation so here we do a sanity check to make sure we haven't
9958 // left any junk around.
9959 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
9960 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
9961 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
9963 for (PreferredActivity pa : pir.filterSet()) {
9964 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
9968 if (removed.size() > 0) {
9969 for (int j=0; j<removed.size(); j++) {
9970 PreferredActivity pa = removed.get(i);
9971 Slog.w(TAG, "Removing dangling preferred activity: "
9972 + pa.mPref.mComponent);
9973 pir.removeFilter(pa);
9975 mSettings.writePackageRestrictionsLPr(
9976 mSettings.mPreferredActivities.keyAt(i));
9982 public boolean isSafeMode() {
9986 public boolean hasSystemUidErrors() {
9987 return mHasSystemUidErrors;
9990 static String arrayToString(int[] array) {
9991 StringBuffer buf = new StringBuffer(128);
9993 if (array != null) {
9994 for (int i=0; i<array.length; i++) {
9995 if (i > 0) buf.append(", ");
9996 buf.append(array[i]);
10000 return buf.toString();
10003 static class DumpState {
10004 public static final int DUMP_LIBS = 1 << 0;
10006 public static final int DUMP_FEATURES = 1 << 1;
10008 public static final int DUMP_RESOLVERS = 1 << 2;
10010 public static final int DUMP_PERMISSIONS = 1 << 3;
10012 public static final int DUMP_PACKAGES = 1 << 4;
10014 public static final int DUMP_SHARED_USERS = 1 << 5;
10016 public static final int DUMP_MESSAGES = 1 << 6;
10018 public static final int DUMP_PROVIDERS = 1 << 7;
10020 public static final int DUMP_VERIFIERS = 1 << 8;
10022 public static final int DUMP_PREFERRED = 1 << 9;
10024 public static final int DUMP_PREFERRED_XML = 1 << 10;
10026 public static final int OPTION_SHOW_FILTERS = 1 << 0;
10028 private int mTypes;
10030 private int mOptions;
10032 private boolean mTitlePrinted;
10034 private SharedUserSetting mSharedUser;
10036 public boolean isDumping(int type) {
10037 if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
10041 return (mTypes & type) != 0;
10044 public void setDump(int type) {
10048 public boolean isOptionEnabled(int option) {
10049 return (mOptions & option) != 0;
10052 public void setOptionEnabled(int option) {
10053 mOptions |= option;
10056 public boolean onTitlePrinted() {
10057 final boolean printed = mTitlePrinted;
10058 mTitlePrinted = true;
10062 public boolean getTitlePrinted() {
10063 return mTitlePrinted;
10066 public void setTitlePrinted(boolean enabled) {
10067 mTitlePrinted = enabled;
10070 public SharedUserSetting getSharedUser() {
10071 return mSharedUser;
10074 public void setSharedUser(SharedUserSetting user) {
10075 mSharedUser = user;
10080 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10081 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
10082 != PackageManager.PERMISSION_GRANTED) {
10083 pw.println("Permission Denial: can't dump ActivityManager from from pid="
10084 + Binder.getCallingPid()
10085 + ", uid=" + Binder.getCallingUid()
10086 + " without permission "
10087 + android.Manifest.permission.DUMP);
10091 DumpState dumpState = new DumpState();
10092 boolean fullPreferred = false;
10094 String packageName = null;
10097 while (opti < args.length) {
10098 String opt = args[opti];
10099 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10103 if ("-a".equals(opt)) {
10104 // Right now we only know how to print all.
10105 } else if ("-h".equals(opt)) {
10106 pw.println("Package manager dump options:");
10107 pw.println(" [-h] [-f] [cmd] ...");
10108 pw.println(" -f: print details of intent filters");
10109 pw.println(" -h: print this help");
10110 pw.println(" cmd may be one of:");
10111 pw.println(" l[ibraries]: list known shared libraries");
10112 pw.println(" f[ibraries]: list device features");
10113 pw.println(" r[esolvers]: dump intent resolvers");
10114 pw.println(" perm[issions]: dump permissions");
10115 pw.println(" pref[erred]: print preferred package settings");
10116 pw.println(" preferred-xml [--full]: print preferred package settings as xml");
10117 pw.println(" prov[iders]: dump content providers");
10118 pw.println(" p[ackages]: dump installed packages");
10119 pw.println(" s[hared-users]: dump shared user IDs");
10120 pw.println(" m[essages]: print collected runtime messages");
10121 pw.println(" v[erifiers]: print package verifier info");
10122 pw.println(" <package.name>: info about given package");
10124 } else if ("-f".equals(opt)) {
10125 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
10127 pw.println("Unknown argument: " + opt + "; use -h for help");
10131 // Is the caller requesting to dump a particular piece of data?
10132 if (opti < args.length) {
10133 String cmd = args[opti];
10135 // Is this a package name?
10136 if ("android".equals(cmd) || cmd.contains(".")) {
10138 } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
10139 dumpState.setDump(DumpState.DUMP_LIBS);
10140 } else if ("f".equals(cmd) || "features".equals(cmd)) {
10141 dumpState.setDump(DumpState.DUMP_FEATURES);
10142 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
10143 dumpState.setDump(DumpState.DUMP_RESOLVERS);
10144 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
10145 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
10146 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
10147 dumpState.setDump(DumpState.DUMP_PREFERRED);
10148 } else if ("preferred-xml".equals(cmd)) {
10149 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
10150 if (opti < args.length && "--full".equals(args[opti])) {
10151 fullPreferred = true;
10154 } else if ("p".equals(cmd) || "packages".equals(cmd)) {
10155 dumpState.setDump(DumpState.DUMP_PACKAGES);
10156 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
10157 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
10158 } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
10159 dumpState.setDump(DumpState.DUMP_PROVIDERS);
10160 } else if ("m".equals(cmd) || "messages".equals(cmd)) {
10161 dumpState.setDump(DumpState.DUMP_MESSAGES);
10162 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
10163 dumpState.setDump(DumpState.DUMP_VERIFIERS);
10168 synchronized (mPackages) {
10169 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
10170 if (dumpState.onTitlePrinted())
10172 pw.println("Verifiers:");
10173 pw.print(" Required: ");
10174 pw.print(mRequiredVerifierPackage);
10175 pw.print(" (uid=");
10176 pw.print(getPackageUid(mRequiredVerifierPackage, 0));
10180 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
10181 if (dumpState.onTitlePrinted())
10183 pw.println("Libraries:");
10184 final Iterator<String> it = mSharedLibraries.keySet().iterator();
10185 while (it.hasNext()) {
10186 String name = it.next();
10190 SharedLibraryEntry ent = mSharedLibraries.get(name);
10191 if (ent.path != null) {
10192 pw.print("(jar) ");
10193 pw.print(ent.path);
10195 pw.print("(apk) ");
10202 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
10203 if (dumpState.onTitlePrinted())
10205 pw.println("Features:");
10206 Iterator<String> it = mAvailableFeatures.keySet().iterator();
10207 while (it.hasNext()) {
10208 String name = it.next();
10214 if (dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
10215 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
10216 : "Activity Resolver Table:", " ", packageName,
10217 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10218 dumpState.setTitlePrinted(true);
10220 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
10221 : "Receiver Resolver Table:", " ", packageName,
10222 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10223 dumpState.setTitlePrinted(true);
10225 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
10226 : "Service Resolver Table:", " ", packageName,
10227 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10228 dumpState.setTitlePrinted(true);
10232 if (dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
10233 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
10234 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
10235 int user = mSettings.mPreferredActivities.keyAt(i);
10237 dumpState.getTitlePrinted()
10238 ? "\nPreferred Activities User " + user + ":"
10239 : "Preferred Activities User " + user + ":", " ",
10240 packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10241 dumpState.setTitlePrinted(true);
10246 if (dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
10248 FileOutputStream fout = new FileOutputStream(fd);
10249 BufferedOutputStream str = new BufferedOutputStream(fout);
10250 XmlSerializer serializer = new FastXmlSerializer();
10252 serializer.setOutput(str, "utf-8");
10253 serializer.startDocument(null, true);
10254 serializer.setFeature(
10255 "http://xmlpull.org/v1/doc/features.html#indent-output", true);
10256 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
10257 serializer.endDocument();
10258 serializer.flush();
10259 } catch (IllegalArgumentException e) {
10260 pw.println("Failed writing: " + e);
10261 } catch (IllegalStateException e) {
10262 pw.println("Failed writing: " + e);
10263 } catch (IOException e) {
10264 pw.println("Failed writing: " + e);
10268 if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
10269 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
10272 if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
10273 boolean printedSomething = false;
10274 for (PackageParser.Provider p : mProvidersByComponent.values()) {
10275 if (packageName != null && !packageName.equals(p.info.packageName)) {
10278 if (!printedSomething) {
10279 if (dumpState.onTitlePrinted())
10281 pw.println("Registered ContentProviders:");
10282 printedSomething = true;
10284 pw.print(" "); pw.print(p.getComponentShortName()); pw.println(":");
10285 pw.print(" "); pw.println(p.toString());
10287 printedSomething = false;
10288 for (Map.Entry<String, PackageParser.Provider> entry : mProviders.entrySet()) {
10289 PackageParser.Provider p = entry.getValue();
10290 if (packageName != null && !packageName.equals(p.info.packageName)) {
10293 if (!printedSomething) {
10294 if (dumpState.onTitlePrinted())
10296 pw.println("ContentProvider Authorities:");
10297 printedSomething = true;
10299 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
10300 pw.print(" "); pw.println(p.toString());
10301 if (p.info != null && p.info.applicationInfo != null) {
10302 final String appInfo = p.info.applicationInfo.toString();
10303 pw.print(" applicationInfo="); pw.println(appInfo);
10308 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
10309 mSettings.dumpPackagesLPr(pw, packageName, dumpState);
10312 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
10313 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
10316 if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
10317 if (dumpState.onTitlePrinted())
10319 mSettings.dumpReadMessagesLPr(pw, dumpState);
10322 pw.println("Package warning messages:");
10323 final File fname = getSettingsProblemFile();
10324 FileInputStream in = null;
10326 in = new FileInputStream(fname);
10327 final int avail = in.available();
10328 final byte[] data = new byte[avail];
10330 pw.print(new String(data));
10331 } catch (FileNotFoundException e) {
10332 } catch (IOException e) {
10337 } catch (IOException e) {
10345 // ------- apps on sdcard specific code -------
10346 static final boolean DEBUG_SD_INSTALL = false;
10348 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
10350 private static final String SD_ENCRYPTION_ALGORITHM = "AES";
10352 private boolean mMediaMounted = false;
10354 private String getEncryptKey() {
10356 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
10357 SD_ENCRYPTION_KEYSTORE_NAME);
10358 if (sdEncKey == null) {
10359 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
10360 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
10361 if (sdEncKey == null) {
10362 Slog.e(TAG, "Failed to create encryption keys");
10367 } catch (NoSuchAlgorithmException nsae) {
10368 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
10370 } catch (IOException ioe) {
10371 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
10377 /* package */static String getTempContainerId() {
10379 String list[] = PackageHelper.getSecureContainerList();
10380 if (list != null) {
10381 for (final String name : list) {
10382 // Ignore null and non-temporary container entries
10383 if (name == null || !name.startsWith(mTempContainerPrefix)) {
10387 String subStr = name.substring(mTempContainerPrefix.length());
10389 int cid = Integer.parseInt(subStr);
10390 if (cid >= tmpIdx) {
10393 } catch (NumberFormatException e) {
10397 return mTempContainerPrefix + tmpIdx;
10401 * Update media status on PackageManager.
10403 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
10404 int callingUid = Binder.getCallingUid();
10405 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10406 throw new SecurityException("Media status can only be updated by the system");
10408 // reader; this apparently protects mMediaMounted, but should probably
10409 // be a different lock in that case.
10410 synchronized (mPackages) {
10411 Log.i(TAG, "Updating external media status from "
10412 + (mMediaMounted ? "mounted" : "unmounted") + " to "
10413 + (mediaStatus ? "mounted" : "unmounted"));
10414 if (DEBUG_SD_INSTALL)
10415 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
10416 + ", mMediaMounted=" + mMediaMounted);
10417 if (mediaStatus == mMediaMounted) {
10418 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
10420 mHandler.sendMessage(msg);
10423 mMediaMounted = mediaStatus;
10425 // Queue up an async operation since the package installation may take a
10427 mHandler.post(new Runnable() {
10428 public void run() {
10429 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
10435 * Called by MountService when the initial ASECs to scan are available.
10436 * Should block until all the ASEC containers are finished being scanned.
10438 public void scanAvailableAsecs() {
10439 updateExternalMediaStatusInner(true, false, false);
10443 * Collect information of applications on external media, map them against
10444 * existing containers and update information based on current mount status.
10445 * Please note that we always have to report status if reportStatus has been
10446 * set to true especially when unloading packages.
10448 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
10449 boolean externalStorage) {
10450 // Collection of uids
10451 int uidArr[] = null;
10452 // Collection of stale containers
10453 HashSet<String> removeCids = new HashSet<String>();
10454 // Collection of packages on external media with valid containers.
10455 HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>();
10456 // Get list of secure containers.
10457 final String list[] = PackageHelper.getSecureContainerList();
10458 if (list == null || list.length == 0) {
10459 Log.i(TAG, "No secure containers on sdcard");
10461 // Process list of secure containers and categorize them
10462 // as active or stale based on their package internal state.
10463 int uidList[] = new int[list.length];
10466 synchronized (mPackages) {
10467 for (String cid : list) {
10468 if (DEBUG_SD_INSTALL)
10469 Log.i(TAG, "Processing container " + cid);
10470 String pkgName = getAsecPackageName(cid);
10471 if (pkgName == null) {
10472 if (DEBUG_SD_INSTALL)
10473 Log.i(TAG, "Container : " + cid + " stale");
10474 removeCids.add(cid);
10477 if (DEBUG_SD_INSTALL)
10478 Log.i(TAG, "Looking for pkg : " + pkgName);
10480 final PackageSetting ps = mSettings.mPackages.get(pkgName);
10482 Log.i(TAG, "Deleting container with no matching settings " + cid);
10483 removeCids.add(cid);
10488 * Skip packages that are not external if we're unmounting
10489 * external storage.
10491 if (externalStorage && !isMounted && !isExternal(ps)) {
10495 final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
10496 // The package status is changed only if the code path
10497 // matches between settings and the container id.
10498 if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
10499 if (DEBUG_SD_INSTALL) {
10500 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
10501 + " at code path: " + ps.codePathString);
10504 // We do have a valid package installed on sdcard
10505 processCids.put(args, ps.codePathString);
10506 final int uid = ps.appId;
10508 uidList[num++] = uid;
10511 Log.i(TAG, "Deleting stale container for " + cid);
10512 removeCids.add(cid);
10519 Arrays.sort(uidList, 0, num);
10520 // Throw away duplicates
10521 uidArr = new int[num];
10522 uidArr[0] = uidList[0];
10524 for (int i = 1; i < num; i++) {
10525 if (uidList[i - 1] != uidList[i]) {
10526 uidArr[di++] = uidList[i];
10531 // Process packages with valid entries.
10533 if (DEBUG_SD_INSTALL)
10534 Log.i(TAG, "Loading packages");
10535 loadMediaPackages(processCids, uidArr, removeCids);
10536 startCleaningPackages();
10538 if (DEBUG_SD_INSTALL)
10539 Log.i(TAG, "Unloading packages");
10540 unloadMediaPackages(processCids, uidArr, reportStatus);
10544 private void sendResourcesChangedBroadcast(boolean mediaStatus, ArrayList<String> pkgList,
10545 int uidArr[], IIntentReceiver finishedReceiver) {
10546 int size = pkgList.size();
10548 // Send broadcasts here
10549 Bundle extras = new Bundle();
10550 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
10551 .toArray(new String[size]));
10552 if (uidArr != null) {
10553 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
10555 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
10556 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
10557 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
10562 * Look at potentially valid container ids from processCids If package
10563 * information doesn't match the one on record or package scanning fails,
10564 * the cid is added to list of removeCids. We currently don't delete stale
10567 private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
10568 HashSet<String> removeCids) {
10569 ArrayList<String> pkgList = new ArrayList<String>();
10570 Set<AsecInstallArgs> keys = processCids.keySet();
10571 boolean doGc = false;
10572 for (AsecInstallArgs args : keys) {
10573 String codePath = processCids.get(args);
10574 if (DEBUG_SD_INSTALL)
10575 Log.i(TAG, "Loading container : " + args.cid);
10576 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10578 // Make sure there are no container errors first.
10579 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
10580 Slog.e(TAG, "Failed to mount cid : " + args.cid
10581 + " when installing from sdcard");
10584 // Check code path here.
10585 if (codePath == null || !codePath.equals(args.getCodePath())) {
10586 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
10587 + " does not match one in settings " + codePath);
10591 int parseFlags = mDefParseFlags;
10592 if (args.isExternal()) {
10593 parseFlags |= PackageParser.PARSE_ON_SDCARD;
10595 if (args.isFwdLocked()) {
10596 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
10600 synchronized (mInstallLock) {
10601 final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
10603 // Scan the package
10606 * TODO why is the lock being held? doPostInstall is
10607 * called in other places without the lock. This needs
10608 * to be straightened out.
10611 synchronized (mPackages) {
10612 retCode = PackageManager.INSTALL_SUCCEEDED;
10613 pkgList.add(pkg.packageName);
10614 // Post process args
10615 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
10616 pkg.applicationInfo.uid);
10619 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard");
10624 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
10625 // Don't destroy container here. Wait till gc clears things
10627 removeCids.add(args.cid);
10632 synchronized (mPackages) {
10633 // If the platform SDK has changed since the last time we booted,
10634 // we need to re-grant app permission to catch any new ones that
10635 // appear. This is really a hack, and means that apps can in some
10636 // cases get permissions that the user didn't initially explicitly
10637 // allow... it would be nice to have some better way to handle
10639 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
10640 if (regrantPermissions)
10641 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
10642 + mSdkVersion + "; regranting permissions for external storage");
10643 mSettings.mExternalSdkPlatform = mSdkVersion;
10645 // Make sure group IDs have been assigned, and any permission
10646 // changes in other apps are accounted for
10647 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
10648 | (regrantPermissions
10649 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
10651 // can downgrade to reader
10652 // Persist settings
10653 mSettings.writeLPr();
10655 // Send a broadcast to let everyone know we are done processing
10656 if (pkgList.size() > 0) {
10657 sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
10659 // Force gc to avoid any stale parser references that we might have.
10661 Runtime.getRuntime().gc();
10663 // List stale containers and destroy stale temporary containers.
10664 if (removeCids != null) {
10665 for (String cid : removeCids) {
10666 if (cid.startsWith(mTempContainerPrefix)) {
10667 Log.i(TAG, "Destroying stale temporary container " + cid);
10668 PackageHelper.destroySdDir(cid);
10670 Log.w(TAG, "Container " + cid + " is stale");
10677 * Utility method to unload a list of specified containers
10679 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
10680 // Just unmount all valid containers.
10681 for (AsecInstallArgs arg : cidArgs) {
10682 synchronized (mInstallLock) {
10683 arg.doPostDeleteLI(false);
10689 * Unload packages mounted on external media. This involves deleting package
10690 * data from internal structures, sending broadcasts about diabled packages,
10691 * gc'ing to free up references, unmounting all secure containers
10692 * corresponding to packages on external media, and posting a
10693 * UPDATED_MEDIA_STATUS message if status has been requested. Please note
10694 * that we always have to post this message if status has been requested no
10697 private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
10698 final boolean reportStatus) {
10699 if (DEBUG_SD_INSTALL)
10700 Log.i(TAG, "unloading media packages");
10701 ArrayList<String> pkgList = new ArrayList<String>();
10702 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
10703 final Set<AsecInstallArgs> keys = processCids.keySet();
10704 for (AsecInstallArgs args : keys) {
10705 String pkgName = args.getPackageName();
10706 if (DEBUG_SD_INSTALL)
10707 Log.i(TAG, "Trying to unload pkg : " + pkgName);
10708 // Delete package internally
10709 PackageRemovedInfo outInfo = new PackageRemovedInfo();
10710 synchronized (mInstallLock) {
10711 boolean res = deletePackageLI(pkgName, null, false, null, null,
10712 PackageManager.DELETE_KEEP_DATA, outInfo, false);
10714 pkgList.add(pkgName);
10716 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
10717 failedList.add(args);
10723 synchronized (mPackages) {
10724 // We didn't update the settings after removing each package;
10725 // write them now for all packages.
10726 mSettings.writeLPr();
10729 // We have to absolutely send UPDATED_MEDIA_STATUS only
10730 // after confirming that all the receivers processed the ordered
10731 // broadcast when packages get disabled, force a gc to clean things up.
10732 // and unload all the containers.
10733 if (pkgList.size() > 0) {
10734 sendResourcesChangedBroadcast(false, pkgList, uidArr, new IIntentReceiver.Stub() {
10735 public void performReceive(Intent intent, int resultCode, String data,
10736 Bundle extras, boolean ordered, boolean sticky,
10737 int sendingUser) throws RemoteException {
10738 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
10739 reportStatus ? 1 : 0, 1, keys);
10740 mHandler.sendMessage(msg);
10744 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
10746 mHandler.sendMessage(msg);
10752 public void movePackage(final String packageName, final IPackageMoveObserver observer,
10754 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
10755 UserHandle user = new UserHandle(UserHandle.getCallingUserId());
10756 int returnCode = PackageManager.MOVE_SUCCEEDED;
10760 synchronized (mPackages) {
10761 PackageParser.Package pkg = mPackages.get(packageName);
10763 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
10765 // Disable moving fwd locked apps and system packages
10766 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
10767 Slog.w(TAG, "Cannot move system application");
10768 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
10769 } else if (pkg.mOperationPending) {
10770 Slog.w(TAG, "Attempt to move package which has pending operations");
10771 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
10773 // Find install location first
10774 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
10775 && (flags & PackageManager.MOVE_INTERNAL) != 0) {
10776 Slog.w(TAG, "Ambigous flags specified for move location.");
10777 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
10779 newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL
10780 : PackageManager.INSTALL_INTERNAL;
10781 currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
10782 : PackageManager.INSTALL_INTERNAL;
10784 if (newFlags == currFlags) {
10785 Slog.w(TAG, "No move required. Trying to move to same location");
10786 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
10788 if (isForwardLocked(pkg)) {
10789 currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10790 newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10794 if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10795 pkg.mOperationPending = true;
10801 * TODO this next block probably shouldn't be inside the lock. We
10802 * can't guarantee these won't change after this is fired off
10805 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
10806 processPendingMove(new MoveParams(null, observer, 0, packageName,
10810 Message msg = mHandler.obtainMessage(INIT_COPY);
10811 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
10812 pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
10813 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
10814 pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user);
10816 mHandler.sendMessage(msg);
10821 private void processPendingMove(final MoveParams mp, final int currentStatus) {
10822 // Queue up an async operation since the package deletion may take a
10824 mHandler.post(new Runnable() {
10825 public void run() {
10826 // TODO fix this; this does nothing.
10827 mHandler.removeCallbacks(this);
10828 int returnCode = currentStatus;
10829 if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
10830 int uidArr[] = null;
10831 ArrayList<String> pkgList = null;
10832 synchronized (mPackages) {
10833 PackageParser.Package pkg = mPackages.get(mp.packageName);
10835 Slog.w(TAG, " Package " + mp.packageName
10836 + " doesn't exist. Aborting move");
10837 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
10838 } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
10839 Slog.w(TAG, "Package " + mp.packageName + " code path changed from "
10840 + mp.srcArgs.getCodePath() + " to "
10841 + pkg.applicationInfo.sourceDir
10842 + " Aborting move and returning error");
10843 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
10845 uidArr = new int[] {
10846 pkg.applicationInfo.uid
10848 pkgList = new ArrayList<String>();
10849 pkgList.add(mp.packageName);
10852 if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10853 // Send resources unavailable broadcast
10854 sendResourcesChangedBroadcast(false, pkgList, uidArr, null);
10855 // Update package code and resource paths
10856 synchronized (mInstallLock) {
10857 synchronized (mPackages) {
10858 PackageParser.Package pkg = mPackages.get(mp.packageName);
10859 // Recheck for package again.
10861 Slog.w(TAG, " Package " + mp.packageName
10862 + " doesn't exist. Aborting move");
10863 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
10864 } else if (!mp.srcArgs.getCodePath().equals(
10865 pkg.applicationInfo.sourceDir)) {
10866 Slog.w(TAG, "Package " + mp.packageName
10867 + " code path changed from " + mp.srcArgs.getCodePath()
10868 + " to " + pkg.applicationInfo.sourceDir
10869 + " Aborting move and returning error");
10870 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
10872 final String oldCodePath = pkg.mPath;
10873 final String newCodePath = mp.targetArgs.getCodePath();
10874 final String newResPath = mp.targetArgs.getResourcePath();
10875 final String newNativePath = mp.targetArgs
10876 .getNativeLibraryPath();
10878 final File newNativeDir = new File(newNativePath);
10880 if (!isForwardLocked(pkg) && !isExternal(pkg)) {
10881 NativeLibraryHelper.copyNativeBinariesIfNeededLI(
10882 new File(newCodePath), newNativeDir);
10884 final int[] users = sUserManager.getUserIds();
10885 for (int user : users) {
10886 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
10887 newNativePath, user) < 0) {
10888 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
10892 if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10893 pkg.mPath = newCodePath;
10894 // Move dex files around
10895 if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) {
10896 // Moving of dex files failed. Set
10897 // error code and abort move.
10898 pkg.mPath = pkg.mScanPath;
10899 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
10903 if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10904 pkg.mScanPath = newCodePath;
10905 pkg.applicationInfo.sourceDir = newCodePath;
10906 pkg.applicationInfo.publicSourceDir = newResPath;
10907 pkg.applicationInfo.nativeLibraryDir = newNativePath;
10908 PackageSetting ps = (PackageSetting) pkg.mExtras;
10909 ps.codePath = new File(pkg.applicationInfo.sourceDir);
10910 ps.codePathString = ps.codePath.getPath();
10911 ps.resourcePath = new File(
10912 pkg.applicationInfo.publicSourceDir);
10913 ps.resourcePathString = ps.resourcePath.getPath();
10914 ps.nativeLibraryPathString = newNativePath;
10915 // Set the application info flag
10917 if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
10918 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
10920 pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
10922 ps.setFlags(pkg.applicationInfo.flags);
10923 mAppDirs.remove(oldCodePath);
10924 mAppDirs.put(newCodePath, pkg);
10925 // Persist settings
10926 mSettings.writeLPr();
10931 // Send resources available broadcast
10932 sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
10935 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
10936 // Clean up failed installation
10937 if (mp.targetArgs != null) {
10938 mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
10942 // Force a gc to clear things up.
10943 Runtime.getRuntime().gc();
10944 // Delete older code
10945 synchronized (mInstallLock) {
10946 mp.srcArgs.doPostDeleteLI(true);
10950 // Allow more operations on this file if we didn't fail because
10951 // an operation was already pending for this package.
10952 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
10953 synchronized (mPackages) {
10954 PackageParser.Package pkg = mPackages.get(mp.packageName);
10956 pkg.mOperationPending = false;
10961 IPackageMoveObserver observer = mp.observer;
10962 if (observer != null) {
10964 observer.packageMoved(mp.packageName, returnCode);
10965 } catch (RemoteException e) {
10966 Log.i(TAG, "Observer no longer exists.");
10973 public boolean setInstallLocation(int loc) {
10974 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
10976 if (getInstallLocation() == loc) {
10979 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
10980 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
10981 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
10982 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
10988 public int getInstallLocation() {
10989 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10990 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
10991 PackageHelper.APP_INSTALL_AUTO);
10994 /** Called by UserManagerService */
10995 void cleanUpUserLILPw(int userHandle) {
10996 mDirtyUsers.remove(userHandle);
10997 mSettings.removeUserLPr(userHandle);
10998 mPendingBroadcasts.remove(userHandle);
10999 if (mInstaller != null) {
11000 // Technically, we shouldn't be doing this with the package lock
11001 // held. However, this is very rare, and there is already so much
11002 // other disk I/O going on, that we'll let it slide for now.
11003 mInstaller.removeUserDataDirs(userHandle);
11007 /** Called by UserManagerService */
11008 void createNewUserLILPw(int userHandle, File path) {
11009 if (mInstaller != null) {
11010 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
11015 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
11016 mContext.enforceCallingOrSelfPermission(
11017 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11018 "Only package verification agents can read the verifier device identity");
11020 synchronized (mPackages) {
11021 return mSettings.getVerifierDeviceIdentityLPw();
11026 public void setPermissionEnforced(String permission, boolean enforced) {
11027 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
11028 if (READ_EXTERNAL_STORAGE.equals(permission)) {
11029 synchronized (mPackages) {
11030 if (mSettings.mReadExternalStorageEnforced == null
11031 || mSettings.mReadExternalStorageEnforced != enforced) {
11032 mSettings.mReadExternalStorageEnforced = enforced;
11033 mSettings.writeLPr();
11036 // kill any non-foreground processes so we restart them and
11037 // grant/revoke the GID.
11038 final IActivityManager am = ActivityManagerNative.getDefault();
11040 final long token = Binder.clearCallingIdentity();
11042 am.killProcessesBelowForeground("setPermissionEnforcement");
11043 } catch (RemoteException e) {
11045 Binder.restoreCallingIdentity(token);
11049 throw new IllegalArgumentException("No selective enforcement for " + permission);
11054 public boolean isPermissionEnforced(String permission) {
11055 final boolean enforcedDefault = isPermissionEnforcedDefault(permission);
11056 synchronized (mPackages) {
11057 return isPermissionEnforcedLocked(permission, enforcedDefault);
11062 * Check if given permission should be enforced by default. Should always be
11063 * called outside of {@link #mPackages} lock.
11065 private boolean isPermissionEnforcedDefault(String permission) {
11066 if (READ_EXTERNAL_STORAGE.equals(permission)) {
11067 return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11068 android.provider.Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, 0)
11076 * Check if user has requested that given permission be enforced, using
11077 * given default if undefined.
11079 private boolean isPermissionEnforcedLocked(String permission, boolean enforcedDefault) {
11080 if (READ_EXTERNAL_STORAGE.equals(permission)) {
11081 if (mSettings.mReadExternalStorageEnforced != null) {
11082 return mSettings.mReadExternalStorageEnforced;
11084 // User hasn't defined; fall back to secure default
11085 return enforcedDefault;
11092 public boolean isStorageLow() {
11093 final long token = Binder.clearCallingIdentity();
11095 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
11096 .getService(DeviceStorageMonitorService.SERVICE);
11097 return dsm.isMemoryLow();
11099 Binder.restoreCallingIdentity(token);