• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 package com.android.server.pm;
18 
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;
33 
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.FastPrintWriter;
39 import com.android.internal.util.FastXmlSerializer;
40 import com.android.internal.util.XmlUtils;
41 import com.android.server.DeviceStorageMonitorService;
42 import com.android.server.EventLogTags;
43 import com.android.server.IntentResolver;
44 
45 import com.android.server.Watchdog;
46 import org.xmlpull.v1.XmlPullParser;
47 import org.xmlpull.v1.XmlPullParserException;
48 import org.xmlpull.v1.XmlSerializer;
49 
50 import android.app.ActivityManager;
51 import android.app.ActivityManagerNative;
52 import android.app.IActivityManager;
53 import android.app.admin.IDevicePolicyManager;
54 import android.app.backup.IBackupManager;
55 import android.content.BroadcastReceiver;
56 import android.content.ComponentName;
57 import android.content.Context;
58 import android.content.IIntentReceiver;
59 import android.content.Intent;
60 import android.content.IntentFilter;
61 import android.content.IntentSender;
62 import android.content.ServiceConnection;
63 import android.content.IntentSender.SendIntentException;
64 import android.content.pm.ActivityInfo;
65 import android.content.pm.ApplicationInfo;
66 import android.content.pm.ContainerEncryptionParams;
67 import android.content.pm.FeatureInfo;
68 import android.content.pm.IPackageDataObserver;
69 import android.content.pm.IPackageDeleteObserver;
70 import android.content.pm.IPackageInstallObserver;
71 import android.content.pm.IPackageManager;
72 import android.content.pm.IPackageMoveObserver;
73 import android.content.pm.IPackageStatsObserver;
74 import android.content.pm.InstrumentationInfo;
75 import android.content.pm.PackageCleanItem;
76 import android.content.pm.PackageInfo;
77 import android.content.pm.PackageInfoLite;
78 import android.content.pm.PackageManager;
79 import android.content.pm.PackageParser;
80 import android.content.pm.PackageUserState;
81 import android.content.pm.PackageParser.ActivityIntentInfo;
82 import android.content.pm.PackageStats;
83 import android.content.pm.ParceledListSlice;
84 import android.content.pm.PermissionGroupInfo;
85 import android.content.pm.PermissionInfo;
86 import android.content.pm.ProviderInfo;
87 import android.content.pm.ResolveInfo;
88 import android.content.pm.ServiceInfo;
89 import android.content.pm.Signature;
90 import android.content.pm.ManifestDigest;
91 import android.content.pm.VerificationParams;
92 import android.content.pm.VerifierDeviceIdentity;
93 import android.content.pm.VerifierInfo;
94 import android.content.res.Resources;
95 import android.net.Uri;
96 import android.os.Binder;
97 import android.os.Build;
98 import android.os.Bundle;
99 import android.os.Environment;
100 import android.os.FileObserver;
101 import android.os.FileUtils;
102 import android.os.Handler;
103 import android.os.HandlerThread;
104 import android.os.IBinder;
105 import android.os.Looper;
106 import android.os.Message;
107 import android.os.Parcel;
108 import android.os.ParcelFileDescriptor;
109 import android.os.Process;
110 import android.os.RemoteException;
111 import android.os.SELinux;
112 import android.os.ServiceManager;
113 import android.os.SystemClock;
114 import android.os.SystemProperties;
115 import android.os.UserHandle;
116 import android.os.Environment.UserEnvironment;
117 import android.os.UserManager;
118 import android.security.KeyStore;
119 import android.security.SystemKeyStore;
120 import android.text.TextUtils;
121 import android.util.DisplayMetrics;
122 import android.util.EventLog;
123 import android.util.Log;
124 import android.util.LogPrinter;
125 import android.util.PrintStreamPrinter;
126 import android.util.Slog;
127 import android.util.SparseArray;
128 import android.util.Xml;
129 import android.view.Display;
130 import android.view.WindowManager;
131 
132 import java.io.BufferedOutputStream;
133 import java.io.File;
134 import java.io.FileDescriptor;
135 import java.io.FileInputStream;
136 import java.io.FileNotFoundException;
137 import java.io.FileOutputStream;
138 import java.io.FileReader;
139 import java.io.FilenameFilter;
140 import java.io.IOException;
141 import java.io.PrintWriter;
142 import java.security.NoSuchAlgorithmException;
143 import java.security.PublicKey;
144 import java.security.cert.CertificateException;
145 import java.text.SimpleDateFormat;
146 import java.util.ArrayList;
147 import java.util.Arrays;
148 import java.util.Collection;
149 import java.util.Collections;
150 import java.util.Comparator;
151 import java.util.Date;
152 import java.util.HashMap;
153 import java.util.HashSet;
154 import java.util.Iterator;
155 import java.util.List;
156 import java.util.Map;
157 import java.util.Set;
158 
159 import libcore.io.ErrnoException;
160 import libcore.io.IoUtils;
161 import libcore.io.Libcore;
162 import libcore.io.StructStat;
163 
164 import com.android.internal.R;
165 
166 /**
167  * Keep track of all those .apks everywhere.
168  *
169  * This is very central to the platform's security; please run the unit
170  * tests whenever making modifications here:
171  *
172 mmm frameworks/base/tests/AndroidTests
173 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
174 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
175  *
176  * {@hide}
177  */
178 public class PackageManagerService extends IPackageManager.Stub {
179     static final String TAG = "PackageManager";
180     static final boolean DEBUG_SETTINGS = false;
181     static final boolean DEBUG_PREFERRED = false;
182     static final boolean DEBUG_UPGRADE = false;
183     private static final boolean DEBUG_INSTALL = false;
184     private static final boolean DEBUG_REMOVE = false;
185     private static final boolean DEBUG_BROADCASTS = false;
186     private static final boolean DEBUG_SHOW_INFO = false;
187     private static final boolean DEBUG_PACKAGE_INFO = false;
188     private static final boolean DEBUG_INTENT_MATCHING = false;
189     private static final boolean DEBUG_PACKAGE_SCANNING = false;
190     private static final boolean DEBUG_APP_DIR_OBSERVER = false;
191     private static final boolean DEBUG_VERIFY = false;
192 
193     private static final int RADIO_UID = Process.PHONE_UID;
194     private static final int LOG_UID = Process.LOG_UID;
195     private static final int NFC_UID = Process.NFC_UID;
196     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
197     private static final int SHELL_UID = Process.SHELL_UID;
198 
199     private static final boolean GET_CERTIFICATES = true;
200 
201     private static final int REMOVE_EVENTS =
202         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
203     private static final int ADD_EVENTS =
204         FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
205 
206     private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
207     // Suffix used during package installation when copying/moving
208     // package apks to install directory.
209     private static final String INSTALL_PACKAGE_SUFFIX = "-";
210 
211     static final int SCAN_MONITOR = 1<<0;
212     static final int SCAN_NO_DEX = 1<<1;
213     static final int SCAN_FORCE_DEX = 1<<2;
214     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
215     static final int SCAN_NEW_INSTALL = 1<<4;
216     static final int SCAN_NO_PATHS = 1<<5;
217     static final int SCAN_UPDATE_TIME = 1<<6;
218     static final int SCAN_DEFER_DEX = 1<<7;
219     static final int SCAN_BOOTING = 1<<8;
220     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<9;
221 
222     static final int REMOVE_CHATTY = 1<<16;
223 
224     /**
225      * Timeout (in milliseconds) after which the watchdog should declare that
226      * our handler thread is wedged.  The usual default for such things is one
227      * minute but we sometimes do very lengthy I/O operations on this thread,
228      * such as installing multi-gigabyte applications, so ours needs to be longer.
229      */
230     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
231 
232     /**
233      * Whether verification is enabled by default.
234      */
235     private static final boolean DEFAULT_VERIFY_ENABLE = true;
236 
237     /**
238      * The default maximum time to wait for the verification agent to return in
239      * milliseconds.
240      */
241     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
242 
243     /**
244      * The default response for package verification timeout.
245      *
246      * This can be either PackageManager.VERIFICATION_ALLOW or
247      * PackageManager.VERIFICATION_REJECT.
248      */
249     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
250 
251     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
252 
253     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
254             DEFAULT_CONTAINER_PACKAGE,
255             "com.android.defcontainer.DefaultContainerService");
256 
257     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
258 
259     private static final String LIB_DIR_NAME = "lib";
260 
261     static final String mTempContainerPrefix = "smdl2tmp";
262 
263     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
264             Process.THREAD_PRIORITY_BACKGROUND);
265     final PackageHandler mHandler;
266 
267     final int mSdkVersion = Build.VERSION.SDK_INT;
268     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
269             ? null : Build.VERSION.CODENAME;
270 
271     final Context mContext;
272     final boolean mFactoryTest;
273     final boolean mOnlyCore;
274     final boolean mNoDexOpt;
275     final DisplayMetrics mMetrics;
276     final int mDefParseFlags;
277     final String[] mSeparateProcesses;
278 
279     // This is where all application persistent data goes.
280     final File mAppDataDir;
281 
282     // This is where all application persistent data goes for secondary users.
283     final File mUserAppDataDir;
284 
285     /** The location for ASEC container files on internal storage. */
286     final String mAsecInternalPath;
287 
288     // This is the object monitoring the framework dir.
289     final FileObserver mFrameworkInstallObserver;
290 
291     // This is the object monitoring the system app dir.
292     final FileObserver mSystemInstallObserver;
293 
294     // This is the object monitoring the privileged system app dir.
295     final FileObserver mPrivilegedInstallObserver;
296 
297     // This is the object monitoring the system app dir.
298     final FileObserver mVendorInstallObserver;
299 
300     // This is the object monitoring mAppInstallDir.
301     final FileObserver mAppInstallObserver;
302 
303     // This is the object monitoring mDrmAppPrivateInstallDir.
304     final FileObserver mDrmAppInstallObserver;
305 
306     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
307     // LOCK HELD.  Can be called with mInstallLock held.
308     final Installer mInstaller;
309 
310     final File mAppInstallDir;
311 
312     /**
313      * Directory to which applications installed internally have native
314      * libraries copied.
315      */
316     private File mAppLibInstallDir;
317 
318     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
319     // apps.
320     final File mDrmAppPrivateInstallDir;
321 
322     // ----------------------------------------------------------------
323 
324     // Lock for state used when installing and doing other long running
325     // operations.  Methods that must be called with this lock held have
326     // the prefix "LI".
327     final Object mInstallLock = new Object();
328 
329     // These are the directories in the 3rd party applications installed dir
330     // that we have currently loaded packages from.  Keys are the application's
331     // installed zip file (absolute codePath), and values are Package.
332     final HashMap<String, PackageParser.Package> mAppDirs =
333             new HashMap<String, PackageParser.Package>();
334 
335     // Information for the parser to write more useful error messages.
336     int mLastScanError;
337 
338     // ----------------------------------------------------------------
339 
340     // Keys are String (package name), values are Package.  This also serves
341     // as the lock for the global state.  Methods that must be called with
342     // this lock held have the prefix "LP".
343     final HashMap<String, PackageParser.Package> mPackages =
344             new HashMap<String, PackageParser.Package>();
345 
346     final Settings mSettings;
347     boolean mRestoredSettings;
348 
349     // Group-ids that are given to all packages as read from etc/permissions/*.xml.
350     int[] mGlobalGids;
351 
352     // These are the built-in uid -> permission mappings that were read from the
353     // etc/permissions.xml file.
354     final SparseArray<HashSet<String>> mSystemPermissions =
355             new SparseArray<HashSet<String>>();
356 
357     static final class SharedLibraryEntry {
358         final String path;
359         final String apk;
360 
SharedLibraryEntry(String _path, String _apk)361         SharedLibraryEntry(String _path, String _apk) {
362             path = _path;
363             apk = _apk;
364         }
365     }
366 
367     // These are the built-in shared libraries that were read from the
368     // etc/permissions.xml file.
369     final HashMap<String, SharedLibraryEntry> mSharedLibraries
370             = new HashMap<String, SharedLibraryEntry>();
371 
372     // Temporary for building the final shared libraries for an .apk.
373     String[] mTmpSharedLibraries = null;
374 
375     // These are the features this devices supports that were read from the
376     // etc/permissions.xml file.
377     final HashMap<String, FeatureInfo> mAvailableFeatures =
378             new HashMap<String, FeatureInfo>();
379 
380     // If mac_permissions.xml was found for seinfo labeling.
381     boolean mFoundPolicyFile;
382 
383     // All available activities, for your resolving pleasure.
384     final ActivityIntentResolver mActivities =
385             new ActivityIntentResolver();
386 
387     // All available receivers, for your resolving pleasure.
388     final ActivityIntentResolver mReceivers =
389             new ActivityIntentResolver();
390 
391     // All available services, for your resolving pleasure.
392     final ServiceIntentResolver mServices = new ServiceIntentResolver();
393 
394     // All available providers, for your resolving pleasure.
395     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
396 
397     // Mapping from provider base names (first directory in content URI codePath)
398     // to the provider information.
399     final HashMap<String, PackageParser.Provider> mProvidersByAuthority =
400             new HashMap<String, PackageParser.Provider>();
401 
402     // Mapping from instrumentation class names to info about them.
403     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
404             new HashMap<ComponentName, PackageParser.Instrumentation>();
405 
406     // Mapping from permission names to info about them.
407     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
408             new HashMap<String, PackageParser.PermissionGroup>();
409 
410     // Packages whose data we have transfered into another package, thus
411     // should no longer exist.
412     final HashSet<String> mTransferedPackages = new HashSet<String>();
413 
414     // Broadcast actions that are only available to the system.
415     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
416 
417     /** List of packages waiting for verification. */
418     final SparseArray<PackageVerificationState> mPendingVerification
419             = new SparseArray<PackageVerificationState>();
420 
421     HashSet<PackageParser.Package> mDeferredDexOpt = null;
422 
423     /** Token for keys in mPendingVerification. */
424     private int mPendingVerificationToken = 0;
425 
426     boolean mSystemReady;
427     boolean mSafeMode;
428     boolean mHasSystemUidErrors;
429 
430     ApplicationInfo mAndroidApplication;
431     final ActivityInfo mResolveActivity = new ActivityInfo();
432     final ResolveInfo mResolveInfo = new ResolveInfo();
433     ComponentName mResolveComponentName;
434     PackageParser.Package mPlatformPackage;
435     ComponentName mCustomResolverComponentName;
436 
437     boolean mResolverReplaced = false;
438 
439     // Set of pending broadcasts for aggregating enable/disable of components.
440     static class PendingPackageBroadcasts {
441         // for each user id, a map of <package name -> components within that package>
442         final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
443 
PendingPackageBroadcasts()444         public PendingPackageBroadcasts() {
445             mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2);
446         }
447 
get(int userId, String packageName)448         public ArrayList<String> get(int userId, String packageName) {
449             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
450             return packages.get(packageName);
451         }
452 
put(int userId, String packageName, ArrayList<String> components)453         public void put(int userId, String packageName, ArrayList<String> components) {
454             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
455             packages.put(packageName, components);
456         }
457 
remove(int userId, String packageName)458         public void remove(int userId, String packageName) {
459             HashMap<String, ArrayList<String>> packages = mUidMap.get(userId);
460             if (packages != null) {
461                 packages.remove(packageName);
462             }
463         }
464 
remove(int userId)465         public void remove(int userId) {
466             mUidMap.remove(userId);
467         }
468 
userIdCount()469         public int userIdCount() {
470             return mUidMap.size();
471         }
472 
userIdAt(int n)473         public int userIdAt(int n) {
474             return mUidMap.keyAt(n);
475         }
476 
packagesForUserId(int userId)477         public HashMap<String, ArrayList<String>> packagesForUserId(int userId) {
478             return mUidMap.get(userId);
479         }
480 
size()481         public int size() {
482             // total number of pending broadcast entries across all userIds
483             int num = 0;
484             for (int i = 0; i< mUidMap.size(); i++) {
485                 num += mUidMap.valueAt(i).size();
486             }
487             return num;
488         }
489 
clear()490         public void clear() {
491             mUidMap.clear();
492         }
493 
getOrAllocate(int userId)494         private HashMap<String, ArrayList<String>> getOrAllocate(int userId) {
495             HashMap<String, ArrayList<String>> map = mUidMap.get(userId);
496             if (map == null) {
497                 map = new HashMap<String, ArrayList<String>>();
498                 mUidMap.put(userId, map);
499             }
500             return map;
501         }
502     }
503     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
504 
505     // Service Connection to remote media container service to copy
506     // package uri's from external media onto secure containers
507     // or internal storage.
508     private IMediaContainerService mContainerService = null;
509 
510     static final int SEND_PENDING_BROADCAST = 1;
511     static final int MCS_BOUND = 3;
512     static final int END_COPY = 4;
513     static final int INIT_COPY = 5;
514     static final int MCS_UNBIND = 6;
515     static final int START_CLEANING_PACKAGE = 7;
516     static final int FIND_INSTALL_LOC = 8;
517     static final int POST_INSTALL = 9;
518     static final int MCS_RECONNECT = 10;
519     static final int MCS_GIVE_UP = 11;
520     static final int UPDATED_MEDIA_STATUS = 12;
521     static final int WRITE_SETTINGS = 13;
522     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
523     static final int PACKAGE_VERIFIED = 15;
524     static final int CHECK_PENDING_VERIFICATION = 16;
525 
526     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
527 
528     // Delay time in millisecs
529     static final int BROADCAST_DELAY = 10 * 1000;
530 
531     static UserManagerService sUserManager;
532 
533     // Stores a list of users whose package restrictions file needs to be updated
534     private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
535 
536     final private DefaultContainerConnection mDefContainerConn =
537             new DefaultContainerConnection();
538     class DefaultContainerConnection implements ServiceConnection {
onServiceConnected(ComponentName name, IBinder service)539         public void onServiceConnected(ComponentName name, IBinder service) {
540             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
541             IMediaContainerService imcs =
542                 IMediaContainerService.Stub.asInterface(service);
543             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
544         }
545 
onServiceDisconnected(ComponentName name)546         public void onServiceDisconnected(ComponentName name) {
547             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
548         }
549     };
550 
551     // Recordkeeping of restore-after-install operations that are currently in flight
552     // between the Package Manager and the Backup Manager
553     class PostInstallData {
554         public InstallArgs args;
555         public PackageInstalledInfo res;
556 
PostInstallData(InstallArgs _a, PackageInstalledInfo _r)557         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
558             args = _a;
559             res = _r;
560         }
561     };
562     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
563     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
564 
565     private final String mRequiredVerifierPackage;
566 
567     class PackageHandler extends Handler {
568         private boolean mBound = false;
569         final ArrayList<HandlerParams> mPendingInstalls =
570             new ArrayList<HandlerParams>();
571 
connectToService()572         private boolean connectToService() {
573             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
574                     " DefaultContainerService");
575             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
576             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
577             if (mContext.bindServiceAsUser(service, mDefContainerConn,
578                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
579                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
580                 mBound = true;
581                 return true;
582             }
583             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
584             return false;
585         }
586 
disconnectService()587         private void disconnectService() {
588             mContainerService = null;
589             mBound = false;
590             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
591             mContext.unbindService(mDefContainerConn);
592             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
593         }
594 
PackageHandler(Looper looper)595         PackageHandler(Looper looper) {
596             super(looper);
597         }
598 
handleMessage(Message msg)599         public void handleMessage(Message msg) {
600             try {
601                 doHandleMessage(msg);
602             } finally {
603                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
604             }
605         }
606 
doHandleMessage(Message msg)607         void doHandleMessage(Message msg) {
608             switch (msg.what) {
609                 case INIT_COPY: {
610                     HandlerParams params = (HandlerParams) msg.obj;
611                     int idx = mPendingInstalls.size();
612                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
613                     // If a bind was already initiated we dont really
614                     // need to do anything. The pending install
615                     // will be processed later on.
616                     if (!mBound) {
617                         // If this is the only one pending we might
618                         // have to bind to the service again.
619                         if (!connectToService()) {
620                             Slog.e(TAG, "Failed to bind to media container service");
621                             params.serviceError();
622                             return;
623                         } else {
624                             // Once we bind to the service, the first
625                             // pending request will be processed.
626                             mPendingInstalls.add(idx, params);
627                         }
628                     } else {
629                         mPendingInstalls.add(idx, params);
630                         // Already bound to the service. Just make
631                         // sure we trigger off processing the first request.
632                         if (idx == 0) {
633                             mHandler.sendEmptyMessage(MCS_BOUND);
634                         }
635                     }
636                     break;
637                 }
638                 case MCS_BOUND: {
639                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
640                     if (msg.obj != null) {
641                         mContainerService = (IMediaContainerService) msg.obj;
642                     }
643                     if (mContainerService == null) {
644                         // Something seriously wrong. Bail out
645                         Slog.e(TAG, "Cannot bind to media container service");
646                         for (HandlerParams params : mPendingInstalls) {
647                             // Indicate service bind error
648                             params.serviceError();
649                         }
650                         mPendingInstalls.clear();
651                     } else if (mPendingInstalls.size() > 0) {
652                         HandlerParams params = mPendingInstalls.get(0);
653                         if (params != null) {
654                             if (params.startCopy()) {
655                                 // We are done...  look for more work or to
656                                 // go idle.
657                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
658                                         "Checking for more work or unbind...");
659                                 // Delete pending install
660                                 if (mPendingInstalls.size() > 0) {
661                                     mPendingInstalls.remove(0);
662                                 }
663                                 if (mPendingInstalls.size() == 0) {
664                                     if (mBound) {
665                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
666                                                 "Posting delayed MCS_UNBIND");
667                                         removeMessages(MCS_UNBIND);
668                                         Message ubmsg = obtainMessage(MCS_UNBIND);
669                                         // Unbind after a little delay, to avoid
670                                         // continual thrashing.
671                                         sendMessageDelayed(ubmsg, 10000);
672                                     }
673                                 } else {
674                                     // There are more pending requests in queue.
675                                     // Just post MCS_BOUND message to trigger processing
676                                     // of next pending install.
677                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
678                                             "Posting MCS_BOUND for next woek");
679                                     mHandler.sendEmptyMessage(MCS_BOUND);
680                                 }
681                             }
682                         }
683                     } else {
684                         // Should never happen ideally.
685                         Slog.w(TAG, "Empty queue");
686                     }
687                     break;
688                 }
689                 case MCS_RECONNECT: {
690                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
691                     if (mPendingInstalls.size() > 0) {
692                         if (mBound) {
693                             disconnectService();
694                         }
695                         if (!connectToService()) {
696                             Slog.e(TAG, "Failed to bind to media container service");
697                             for (HandlerParams params : mPendingInstalls) {
698                                 // Indicate service bind error
699                                 params.serviceError();
700                             }
701                             mPendingInstalls.clear();
702                         }
703                     }
704                     break;
705                 }
706                 case MCS_UNBIND: {
707                     // If there is no actual work left, then time to unbind.
708                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
709 
710                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
711                         if (mBound) {
712                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
713 
714                             disconnectService();
715                         }
716                     } else if (mPendingInstalls.size() > 0) {
717                         // There are more pending requests in queue.
718                         // Just post MCS_BOUND message to trigger processing
719                         // of next pending install.
720                         mHandler.sendEmptyMessage(MCS_BOUND);
721                     }
722 
723                     break;
724                 }
725                 case MCS_GIVE_UP: {
726                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
727                     mPendingInstalls.remove(0);
728                     break;
729                 }
730                 case SEND_PENDING_BROADCAST: {
731                     String packages[];
732                     ArrayList<String> components[];
733                     int size = 0;
734                     int uids[];
735                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
736                     synchronized (mPackages) {
737                         if (mPendingBroadcasts == null) {
738                             return;
739                         }
740                         size = mPendingBroadcasts.size();
741                         if (size <= 0) {
742                             // Nothing to be done. Just return
743                             return;
744                         }
745                         packages = new String[size];
746                         components = new ArrayList[size];
747                         uids = new int[size];
748                         int i = 0;  // filling out the above arrays
749 
750                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
751                             int packageUserId = mPendingBroadcasts.userIdAt(n);
752                             Iterator<Map.Entry<String, ArrayList<String>>> it
753                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
754                                             .entrySet().iterator();
755                             while (it.hasNext() && i < size) {
756                                 Map.Entry<String, ArrayList<String>> ent = it.next();
757                                 packages[i] = ent.getKey();
758                                 components[i] = ent.getValue();
759                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
760                                 uids[i] = (ps != null)
761                                         ? UserHandle.getUid(packageUserId, ps.appId)
762                                         : -1;
763                                 i++;
764                             }
765                         }
766                         size = i;
767                         mPendingBroadcasts.clear();
768                     }
769                     // Send broadcasts
770                     for (int i = 0; i < size; i++) {
771                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
772                     }
773                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
774                     break;
775                 }
776                 case START_CLEANING_PACKAGE: {
777                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
778                     final String packageName = (String)msg.obj;
779                     final int userId = msg.arg1;
780                     final boolean andCode = msg.arg2 != 0;
781                     synchronized (mPackages) {
782                         if (userId == UserHandle.USER_ALL) {
783                             int[] users = sUserManager.getUserIds();
784                             for (int user : users) {
785                                 mSettings.addPackageToCleanLPw(
786                                         new PackageCleanItem(user, packageName, andCode));
787                             }
788                         } else {
789                             mSettings.addPackageToCleanLPw(
790                                     new PackageCleanItem(userId, packageName, andCode));
791                         }
792                     }
793                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
794                     startCleaningPackages();
795                 } break;
796                 case POST_INSTALL: {
797                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
798                     PostInstallData data = mRunningInstalls.get(msg.arg1);
799                     mRunningInstalls.delete(msg.arg1);
800                     boolean deleteOld = false;
801 
802                     if (data != null) {
803                         InstallArgs args = data.args;
804                         PackageInstalledInfo res = data.res;
805 
806                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
807                             res.removedInfo.sendBroadcast(false, true, false);
808                             Bundle extras = new Bundle(1);
809                             extras.putInt(Intent.EXTRA_UID, res.uid);
810                             // Determine the set of users who are adding this
811                             // package for the first time vs. those who are seeing
812                             // an update.
813                             int[] firstUsers;
814                             int[] updateUsers = new int[0];
815                             if (res.origUsers == null || res.origUsers.length == 0) {
816                                 firstUsers = res.newUsers;
817                             } else {
818                                 firstUsers = new int[0];
819                                 for (int i=0; i<res.newUsers.length; i++) {
820                                     int user = res.newUsers[i];
821                                     boolean isNew = true;
822                                     for (int j=0; j<res.origUsers.length; j++) {
823                                         if (res.origUsers[j] == user) {
824                                             isNew = false;
825                                             break;
826                                         }
827                                     }
828                                     if (isNew) {
829                                         int[] newFirst = new int[firstUsers.length+1];
830                                         System.arraycopy(firstUsers, 0, newFirst, 0,
831                                                 firstUsers.length);
832                                         newFirst[firstUsers.length] = user;
833                                         firstUsers = newFirst;
834                                     } else {
835                                         int[] newUpdate = new int[updateUsers.length+1];
836                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
837                                                 updateUsers.length);
838                                         newUpdate[updateUsers.length] = user;
839                                         updateUsers = newUpdate;
840                                     }
841                                 }
842                             }
843                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
844                                     res.pkg.applicationInfo.packageName,
845                                     extras, null, null, firstUsers);
846                             final boolean update = res.removedInfo.removedPackage != null;
847                             if (update) {
848                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
849                             }
850                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
851                                     res.pkg.applicationInfo.packageName,
852                                     extras, null, null, updateUsers);
853                             if (update) {
854                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
855                                         res.pkg.applicationInfo.packageName,
856                                         extras, null, null, updateUsers);
857                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
858                                         null, null,
859                                         res.pkg.applicationInfo.packageName, null, updateUsers);
860 
861                                 // treat asec-hosted packages like removable media on upgrade
862                                 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
863                                     if (DEBUG_INSTALL) {
864                                         Slog.i(TAG, "upgrading pkg " + res.pkg
865                                                 + " is ASEC-hosted -> AVAILABLE");
866                                     }
867                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
868                                     ArrayList<String> pkgList = new ArrayList<String>(1);
869                                     pkgList.add(res.pkg.applicationInfo.packageName);
870                                     sendResourcesChangedBroadcast(true, true,
871                                             pkgList,uidArray, null);
872                                 }
873                             }
874                             if (res.removedInfo.args != null) {
875                                 // Remove the replaced package's older resources safely now
876                                 deleteOld = true;
877                             }
878 
879                             // Log current value of "unknown sources" setting
880                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
881                                 getUnknownSourcesSettings());
882                         }
883                         // Force a gc to clear up things
884                         Runtime.getRuntime().gc();
885                         // We delete after a gc for applications  on sdcard.
886                         if (deleteOld) {
887                             synchronized (mInstallLock) {
888                                 res.removedInfo.args.doPostDeleteLI(true);
889                             }
890                         }
891                         if (args.observer != null) {
892                             try {
893                                 args.observer.packageInstalled(res.name, res.returnCode);
894                             } catch (RemoteException e) {
895                                 Slog.i(TAG, "Observer no longer exists.");
896                             }
897                         }
898                     } else {
899                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
900                     }
901                 } break;
902                 case UPDATED_MEDIA_STATUS: {
903                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
904                     boolean reportStatus = msg.arg1 == 1;
905                     boolean doGc = msg.arg2 == 1;
906                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
907                     if (doGc) {
908                         // Force a gc to clear up stale containers.
909                         Runtime.getRuntime().gc();
910                     }
911                     if (msg.obj != null) {
912                         @SuppressWarnings("unchecked")
913                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
914                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
915                         // Unload containers
916                         unloadAllContainers(args);
917                     }
918                     if (reportStatus) {
919                         try {
920                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
921                             PackageHelper.getMountService().finishMediaUpdate();
922                         } catch (RemoteException e) {
923                             Log.e(TAG, "MountService not running?");
924                         }
925                     }
926                 } break;
927                 case WRITE_SETTINGS: {
928                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
929                     synchronized (mPackages) {
930                         removeMessages(WRITE_SETTINGS);
931                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
932                         mSettings.writeLPr();
933                         mDirtyUsers.clear();
934                     }
935                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
936                 } break;
937                 case WRITE_PACKAGE_RESTRICTIONS: {
938                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
939                     synchronized (mPackages) {
940                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
941                         for (int userId : mDirtyUsers) {
942                             mSettings.writePackageRestrictionsLPr(userId);
943                         }
944                         mDirtyUsers.clear();
945                     }
946                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
947                 } break;
948                 case CHECK_PENDING_VERIFICATION: {
949                     final int verificationId = msg.arg1;
950                     final PackageVerificationState state = mPendingVerification.get(verificationId);
951 
952                     if ((state != null) && !state.timeoutExtended()) {
953                         final InstallArgs args = state.getInstallArgs();
954                         Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
955                         mPendingVerification.remove(verificationId);
956 
957                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
958 
959                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
960                             Slog.i(TAG, "Continuing with installation of "
961                                     + args.packageURI.toString());
962                             state.setVerifierResponse(Binder.getCallingUid(),
963                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
964                             broadcastPackageVerified(verificationId, args.packageURI,
965                                     PackageManager.VERIFICATION_ALLOW,
966                                     state.getInstallArgs().getUser());
967                             try {
968                                 ret = args.copyApk(mContainerService, true);
969                             } catch (RemoteException e) {
970                                 Slog.e(TAG, "Could not contact the ContainerService");
971                             }
972                         } else {
973                             broadcastPackageVerified(verificationId, args.packageURI,
974                                     PackageManager.VERIFICATION_REJECT,
975                                     state.getInstallArgs().getUser());
976                         }
977 
978                         processPendingInstall(args, ret);
979                         mHandler.sendEmptyMessage(MCS_UNBIND);
980                     }
981                     break;
982                 }
983                 case PACKAGE_VERIFIED: {
984                     final int verificationId = msg.arg1;
985 
986                     final PackageVerificationState state = mPendingVerification.get(verificationId);
987                     if (state == null) {
988                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
989                         break;
990                     }
991 
992                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
993 
994                     state.setVerifierResponse(response.callerUid, response.code);
995 
996                     if (state.isVerificationComplete()) {
997                         mPendingVerification.remove(verificationId);
998 
999                         final InstallArgs args = state.getInstallArgs();
1000 
1001                         int ret;
1002                         if (state.isInstallAllowed()) {
1003                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1004                             broadcastPackageVerified(verificationId, args.packageURI,
1005                                     response.code, state.getInstallArgs().getUser());
1006                             try {
1007                                 ret = args.copyApk(mContainerService, true);
1008                             } catch (RemoteException e) {
1009                                 Slog.e(TAG, "Could not contact the ContainerService");
1010                             }
1011                         } else {
1012                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1013                         }
1014 
1015                         processPendingInstall(args, ret);
1016 
1017                         mHandler.sendEmptyMessage(MCS_UNBIND);
1018                     }
1019 
1020                     break;
1021                 }
1022             }
1023         }
1024     }
1025 
scheduleWriteSettingsLocked()1026     void scheduleWriteSettingsLocked() {
1027         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1028             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1029         }
1030     }
1031 
scheduleWritePackageRestrictionsLocked(int userId)1032     void scheduleWritePackageRestrictionsLocked(int userId) {
1033         if (!sUserManager.exists(userId)) return;
1034         mDirtyUsers.add(userId);
1035         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1036             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1037         }
1038     }
1039 
main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1040     public static final IPackageManager main(Context context, Installer installer,
1041             boolean factoryTest, boolean onlyCore) {
1042         PackageManagerService m = new PackageManagerService(context, installer,
1043                 factoryTest, onlyCore);
1044         ServiceManager.addService("package", m);
1045         return m;
1046     }
1047 
splitString(String str, char sep)1048     static String[] splitString(String str, char sep) {
1049         int count = 1;
1050         int i = 0;
1051         while ((i=str.indexOf(sep, i)) >= 0) {
1052             count++;
1053             i++;
1054         }
1055 
1056         String[] res = new String[count];
1057         i=0;
1058         count = 0;
1059         int lastI=0;
1060         while ((i=str.indexOf(sep, i)) >= 0) {
1061             res[count] = str.substring(lastI, i);
1062             count++;
1063             i++;
1064             lastI = i;
1065         }
1066         res[count] = str.substring(lastI, str.length());
1067         return res;
1068     }
1069 
PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1070     public PackageManagerService(Context context, Installer installer,
1071             boolean factoryTest, boolean onlyCore) {
1072         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1073                 SystemClock.uptimeMillis());
1074 
1075         if (mSdkVersion <= 0) {
1076             Slog.w(TAG, "**** ro.build.version.sdk not set!");
1077         }
1078 
1079         mContext = context;
1080         mFactoryTest = factoryTest;
1081         mOnlyCore = onlyCore;
1082         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1083         mMetrics = new DisplayMetrics();
1084         mSettings = new Settings(context);
1085         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1086                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1087         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1088                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1089         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1090                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1091         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1092                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1093         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1094                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1095         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1096                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1097 
1098         String separateProcesses = SystemProperties.get("debug.separate_processes");
1099         if (separateProcesses != null && separateProcesses.length() > 0) {
1100             if ("*".equals(separateProcesses)) {
1101                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1102                 mSeparateProcesses = null;
1103                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1104             } else {
1105                 mDefParseFlags = 0;
1106                 mSeparateProcesses = separateProcesses.split(",");
1107                 Slog.w(TAG, "Running with debug.separate_processes: "
1108                         + separateProcesses);
1109             }
1110         } else {
1111             mDefParseFlags = 0;
1112             mSeparateProcesses = null;
1113         }
1114 
1115         mInstaller = installer;
1116 
1117         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
1118         Display d = wm.getDefaultDisplay();
1119         d.getMetrics(mMetrics);
1120 
1121         synchronized (mInstallLock) {
1122         // writer
1123         synchronized (mPackages) {
1124             mHandlerThread.start();
1125             mHandler = new PackageHandler(mHandlerThread.getLooper());
1126             Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName(),
1127                     WATCHDOG_TIMEOUT);
1128 
1129             File dataDir = Environment.getDataDirectory();
1130             mAppDataDir = new File(dataDir, "data");
1131             mAppInstallDir = new File(dataDir, "app");
1132             mAppLibInstallDir = new File(dataDir, "app-lib");
1133             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1134             mUserAppDataDir = new File(dataDir, "user");
1135             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1136 
1137             sUserManager = new UserManagerService(context, this,
1138                     mInstallLock, mPackages);
1139 
1140             readPermissions();
1141 
1142             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1143 
1144             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1145                     mSdkVersion, mOnlyCore);
1146 
1147             String customResolverActivity = Resources.getSystem().getString(
1148                     R.string.config_customResolverActivity);
1149             if (TextUtils.isEmpty(customResolverActivity)) {
1150                 customResolverActivity = null;
1151             } else {
1152                 mCustomResolverComponentName = ComponentName.unflattenFromString(
1153                         customResolverActivity);
1154             }
1155 
1156             long startTime = SystemClock.uptimeMillis();
1157 
1158             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1159                     startTime);
1160 
1161             // Set flag to monitor and not change apk file paths when
1162             // scanning install directories.
1163             int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1164             if (mNoDexOpt) {
1165                 Slog.w(TAG, "Running ENG build: no pre-dexopt!");
1166                 scanMode |= SCAN_NO_DEX;
1167             }
1168 
1169             final HashSet<String> alreadyDexOpted = new HashSet<String>();
1170 
1171             /**
1172              * Add everything in the in the boot class path to the
1173              * list of process files because dexopt will have been run
1174              * if necessary during zygote startup.
1175              */
1176             String bootClassPath = System.getProperty("java.boot.class.path");
1177             if (bootClassPath != null) {
1178                 String[] paths = splitString(bootClassPath, ':');
1179                 for (int i=0; i<paths.length; i++) {
1180                     alreadyDexOpted.add(paths[i]);
1181                 }
1182             } else {
1183                 Slog.w(TAG, "No BOOTCLASSPATH found!");
1184             }
1185 
1186             boolean didDexOpt = false;
1187 
1188             /**
1189              * Ensure all external libraries have had dexopt run on them.
1190              */
1191             if (mSharedLibraries.size() > 0) {
1192                 Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator();
1193                 while (libs.hasNext()) {
1194                     String lib = libs.next().path;
1195                     if (lib == null) {
1196                         continue;
1197                     }
1198                     try {
1199                         if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
1200                             alreadyDexOpted.add(lib);
1201                             mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
1202                             didDexOpt = true;
1203                         }
1204                     } catch (FileNotFoundException e) {
1205                         Slog.w(TAG, "Library not found: " + lib);
1206                     } catch (IOException e) {
1207                         Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1208                                 + e.getMessage());
1209                     }
1210                 }
1211             }
1212 
1213             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1214 
1215             // Gross hack for now: we know this file doesn't contain any
1216             // code, so don't dexopt it to avoid the resulting log spew.
1217             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1218 
1219             // Gross hack for now: we know this file is only part of
1220             // the boot class path for art, so don't dexopt it to
1221             // avoid the resulting log spew.
1222             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1223 
1224             /**
1225              * And there are a number of commands implemented in Java, which
1226              * we currently need to do the dexopt on so that they can be
1227              * run from a non-root shell.
1228              */
1229             String[] frameworkFiles = frameworkDir.list();
1230             if (frameworkFiles != null) {
1231                 for (int i=0; i<frameworkFiles.length; i++) {
1232                     File libPath = new File(frameworkDir, frameworkFiles[i]);
1233                     String path = libPath.getPath();
1234                     // Skip the file if we alrady did it.
1235                     if (alreadyDexOpted.contains(path)) {
1236                         continue;
1237                     }
1238                     // Skip the file if it is not a type we want to dexopt.
1239                     if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1240                         continue;
1241                     }
1242                     try {
1243                         if (dalvik.system.DexFile.isDexOptNeeded(path)) {
1244                             mInstaller.dexopt(path, Process.SYSTEM_UID, true);
1245                             didDexOpt = true;
1246                         }
1247                     } catch (FileNotFoundException e) {
1248                         Slog.w(TAG, "Jar not found: " + path);
1249                     } catch (IOException e) {
1250                         Slog.w(TAG, "Exception reading jar: " + path, e);
1251                     }
1252                 }
1253             }
1254 
1255             if (didDexOpt) {
1256                 File dalvikCacheDir = new File(dataDir, "dalvik-cache");
1257 
1258                 // If we had to do a dexopt of one of the previous
1259                 // things, then something on the system has changed.
1260                 // Consider this significant, and wipe away all other
1261                 // existing dexopt files to ensure we don't leave any
1262                 // dangling around.
1263                 String[] files = dalvikCacheDir.list();
1264                 if (files != null) {
1265                     for (int i=0; i<files.length; i++) {
1266                         String fn = files[i];
1267                         if (fn.startsWith("data@app@")
1268                                 || fn.startsWith("data@app-private@")) {
1269                             Slog.i(TAG, "Pruning dalvik file: " + fn);
1270                             (new File(dalvikCacheDir, fn)).delete();
1271                         }
1272                     }
1273                 }
1274             }
1275 
1276             // Find base frameworks (resource packages without code).
1277             mFrameworkInstallObserver = new AppDirObserver(
1278                 frameworkDir.getPath(), OBSERVER_EVENTS, true, false);
1279             mFrameworkInstallObserver.startWatching();
1280             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1281                     | PackageParser.PARSE_IS_SYSTEM_DIR
1282                     | PackageParser.PARSE_IS_PRIVILEGED,
1283                     scanMode | SCAN_NO_DEX, 0);
1284 
1285             // Collected privileged system packages.
1286             File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1287             mPrivilegedInstallObserver = new AppDirObserver(
1288                     privilegedAppDir.getPath(), OBSERVER_EVENTS, true, true);
1289             mPrivilegedInstallObserver.startWatching();
1290                 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1291                         | PackageParser.PARSE_IS_SYSTEM_DIR
1292                         | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0);
1293 
1294             // Collect ordinary system packages.
1295             File systemAppDir = new File(Environment.getRootDirectory(), "app");
1296             mSystemInstallObserver = new AppDirObserver(
1297                 systemAppDir.getPath(), OBSERVER_EVENTS, true, false);
1298             mSystemInstallObserver.startWatching();
1299             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1300                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1301 
1302             // Collect all vendor packages.
1303             File vendorAppDir = new File("/vendor/app");
1304             mVendorInstallObserver = new AppDirObserver(
1305                 vendorAppDir.getPath(), OBSERVER_EVENTS, true, false);
1306             mVendorInstallObserver.startWatching();
1307             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1308                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1309 
1310             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1311             mInstaller.moveFiles();
1312 
1313             // Prune any system packages that no longer exist.
1314             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1315             if (!mOnlyCore) {
1316                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1317                 while (psit.hasNext()) {
1318                     PackageSetting ps = psit.next();
1319 
1320                     /*
1321                      * If this is not a system app, it can't be a
1322                      * disable system app.
1323                      */
1324                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1325                         continue;
1326                     }
1327 
1328                     /*
1329                      * If the package is scanned, it's not erased.
1330                      */
1331                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1332                     if (scannedPkg != null) {
1333                         /*
1334                          * If the system app is both scanned and in the
1335                          * disabled packages list, then it must have been
1336                          * added via OTA. Remove it from the currently
1337                          * scanned package so the previously user-installed
1338                          * application can be scanned.
1339                          */
1340                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1341                             Slog.i(TAG, "Expecting better updatd system app for " + ps.name
1342                                     + "; removing system app");
1343                             removePackageLI(ps, true);
1344                         }
1345 
1346                         continue;
1347                     }
1348 
1349                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1350                         psit.remove();
1351                         String msg = "System package " + ps.name
1352                                 + " no longer exists; wiping its data";
1353                         reportSettingsProblem(Log.WARN, msg);
1354                         removeDataDirsLI(ps.name);
1355                     } else {
1356                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1357                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1358                             possiblyDeletedUpdatedSystemApps.add(ps.name);
1359                         }
1360                     }
1361                 }
1362             }
1363 
1364             //look for any incomplete package installations
1365             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1366             //clean up list
1367             for(int i = 0; i < deletePkgsList.size(); i++) {
1368                 //clean up here
1369                 cleanupInstallFailedPackage(deletePkgsList.get(i));
1370             }
1371             //delete tmp files
1372             deleteTempPackageFiles();
1373 
1374             // Remove any shared userIDs that have no associated packages
1375             mSettings.pruneSharedUsersLPw();
1376 
1377             if (!mOnlyCore) {
1378                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1379                         SystemClock.uptimeMillis());
1380                 mAppInstallObserver = new AppDirObserver(
1381                     mAppInstallDir.getPath(), OBSERVER_EVENTS, false, false);
1382                 mAppInstallObserver.startWatching();
1383                 scanDirLI(mAppInstallDir, 0, scanMode, 0);
1384 
1385                 mDrmAppInstallObserver = new AppDirObserver(
1386                     mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false, false);
1387                 mDrmAppInstallObserver.startWatching();
1388                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1389                         scanMode, 0);
1390 
1391                 /**
1392                  * Remove disable package settings for any updated system
1393                  * apps that were removed via an OTA. If they're not a
1394                  * previously-updated app, remove them completely.
1395                  * Otherwise, just revoke their system-level permissions.
1396                  */
1397                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1398                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1399                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1400 
1401                     String msg;
1402                     if (deletedPkg == null) {
1403                         msg = "Updated system package " + deletedAppName
1404                                 + " no longer exists; wiping its data";
1405                         removeDataDirsLI(deletedAppName);
1406                     } else {
1407                         msg = "Updated system app + " + deletedAppName
1408                                 + " no longer present; removing system privileges for "
1409                                 + deletedAppName;
1410 
1411                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1412 
1413                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1414                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1415                     }
1416                     reportSettingsProblem(Log.WARN, msg);
1417                 }
1418             } else {
1419                 mAppInstallObserver = null;
1420                 mDrmAppInstallObserver = null;
1421             }
1422 
1423             // Now that we know all of the shared libraries, update all clients to have
1424             // the correct library paths.
1425             updateAllSharedLibrariesLPw();
1426 
1427             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1428                     SystemClock.uptimeMillis());
1429             Slog.i(TAG, "Time to scan packages: "
1430                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
1431                     + " seconds");
1432 
1433             // If the platform SDK has changed since the last time we booted,
1434             // we need to re-grant app permission to catch any new ones that
1435             // appear.  This is really a hack, and means that apps can in some
1436             // cases get permissions that the user didn't initially explicitly
1437             // allow...  it would be nice to have some better way to handle
1438             // this situation.
1439             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1440                     != mSdkVersion;
1441             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1442                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1443                     + "; regranting permissions for internal storage");
1444             mSettings.mInternalSdkPlatform = mSdkVersion;
1445 
1446             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1447                     | (regrantPermissions
1448                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1449                             : 0));
1450 
1451             // If this is the first boot, and it is a normal boot, then
1452             // we need to initialize the default preferred apps.
1453             if (!mRestoredSettings && !onlyCore) {
1454                 mSettings.readDefaultPreferredAppsLPw(this, 0);
1455             }
1456 
1457             // can downgrade to reader
1458             mSettings.writeLPr();
1459 
1460             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1461                     SystemClock.uptimeMillis());
1462 
1463             // Now after opening every single application zip, make sure they
1464             // are all flushed.  Not really needed, but keeps things nice and
1465             // tidy.
1466             Runtime.getRuntime().gc();
1467 
1468             mRequiredVerifierPackage = getRequiredVerifierLPr();
1469         } // synchronized (mPackages)
1470         } // synchronized (mInstallLock)
1471     }
1472 
isFirstBoot()1473     public boolean isFirstBoot() {
1474         return !mRestoredSettings;
1475     }
1476 
isOnlyCoreApps()1477     public boolean isOnlyCoreApps() {
1478         return mOnlyCore;
1479     }
1480 
getRequiredVerifierLPr()1481     private String getRequiredVerifierLPr() {
1482         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1483         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1484                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1485 
1486         String requiredVerifier = null;
1487 
1488         final int N = receivers.size();
1489         for (int i = 0; i < N; i++) {
1490             final ResolveInfo info = receivers.get(i);
1491 
1492             if (info.activityInfo == null) {
1493                 continue;
1494             }
1495 
1496             final String packageName = info.activityInfo.packageName;
1497 
1498             final PackageSetting ps = mSettings.mPackages.get(packageName);
1499             if (ps == null) {
1500                 continue;
1501             }
1502 
1503             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1504             if (!gp.grantedPermissions
1505                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1506                 continue;
1507             }
1508 
1509             if (requiredVerifier != null) {
1510                 throw new RuntimeException("There can be only one required verifier");
1511             }
1512 
1513             requiredVerifier = packageName;
1514         }
1515 
1516         return requiredVerifier;
1517     }
1518 
1519     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)1520     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1521             throws RemoteException {
1522         try {
1523             return super.onTransact(code, data, reply, flags);
1524         } catch (RuntimeException e) {
1525             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1526                 Slog.wtf(TAG, "Package Manager Crash", e);
1527             }
1528             throw e;
1529         }
1530     }
1531 
cleanupInstallFailedPackage(PackageSetting ps)1532     void cleanupInstallFailedPackage(PackageSetting ps) {
1533         Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
1534         removeDataDirsLI(ps.name);
1535         if (ps.codePath != null) {
1536             if (!ps.codePath.delete()) {
1537                 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
1538             }
1539         }
1540         if (ps.resourcePath != null) {
1541             if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
1542                 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
1543             }
1544         }
1545         mSettings.removePackageLPw(ps.name);
1546     }
1547 
readPermissions()1548     void readPermissions() {
1549         // Read permissions from .../etc/permission directory.
1550         File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
1551         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
1552             Slog.w(TAG, "No directory " + libraryDir + ", skipping");
1553             return;
1554         }
1555         if (!libraryDir.canRead()) {
1556             Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
1557             return;
1558         }
1559 
1560         // Iterate over the files in the directory and scan .xml files
1561         for (File f : libraryDir.listFiles()) {
1562             // We'll read platform.xml last
1563             if (f.getPath().endsWith("etc/permissions/platform.xml")) {
1564                 continue;
1565             }
1566 
1567             if (!f.getPath().endsWith(".xml")) {
1568                 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
1569                 continue;
1570             }
1571             if (!f.canRead()) {
1572                 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
1573                 continue;
1574             }
1575 
1576             readPermissionsFromXml(f);
1577         }
1578 
1579         // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
1580         final File permFile = new File(Environment.getRootDirectory(),
1581                 "etc/permissions/platform.xml");
1582         readPermissionsFromXml(permFile);
1583     }
1584 
readPermissionsFromXml(File permFile)1585     private void readPermissionsFromXml(File permFile) {
1586         FileReader permReader = null;
1587         try {
1588             permReader = new FileReader(permFile);
1589         } catch (FileNotFoundException e) {
1590             Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
1591             return;
1592         }
1593 
1594         try {
1595             XmlPullParser parser = Xml.newPullParser();
1596             parser.setInput(permReader);
1597 
1598             XmlUtils.beginDocument(parser, "permissions");
1599 
1600             while (true) {
1601                 XmlUtils.nextElement(parser);
1602                 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
1603                     break;
1604                 }
1605 
1606                 String name = parser.getName();
1607                 if ("group".equals(name)) {
1608                     String gidStr = parser.getAttributeValue(null, "gid");
1609                     if (gidStr != null) {
1610                         int gid = Process.getGidForName(gidStr);
1611                         mGlobalGids = appendInt(mGlobalGids, gid);
1612                     } else {
1613                         Slog.w(TAG, "<group> without gid at "
1614                                 + parser.getPositionDescription());
1615                     }
1616 
1617                     XmlUtils.skipCurrentTag(parser);
1618                     continue;
1619                 } else if ("permission".equals(name)) {
1620                     String perm = parser.getAttributeValue(null, "name");
1621                     if (perm == null) {
1622                         Slog.w(TAG, "<permission> without name at "
1623                                 + parser.getPositionDescription());
1624                         XmlUtils.skipCurrentTag(parser);
1625                         continue;
1626                     }
1627                     perm = perm.intern();
1628                     readPermission(parser, perm);
1629 
1630                 } else if ("assign-permission".equals(name)) {
1631                     String perm = parser.getAttributeValue(null, "name");
1632                     if (perm == null) {
1633                         Slog.w(TAG, "<assign-permission> without name at "
1634                                 + parser.getPositionDescription());
1635                         XmlUtils.skipCurrentTag(parser);
1636                         continue;
1637                     }
1638                     String uidStr = parser.getAttributeValue(null, "uid");
1639                     if (uidStr == null) {
1640                         Slog.w(TAG, "<assign-permission> without uid at "
1641                                 + parser.getPositionDescription());
1642                         XmlUtils.skipCurrentTag(parser);
1643                         continue;
1644                     }
1645                     int uid = Process.getUidForName(uidStr);
1646                     if (uid < 0) {
1647                         Slog.w(TAG, "<assign-permission> with unknown uid \""
1648                                 + uidStr + "\" at "
1649                                 + parser.getPositionDescription());
1650                         XmlUtils.skipCurrentTag(parser);
1651                         continue;
1652                     }
1653                     perm = perm.intern();
1654                     HashSet<String> perms = mSystemPermissions.get(uid);
1655                     if (perms == null) {
1656                         perms = new HashSet<String>();
1657                         mSystemPermissions.put(uid, perms);
1658                     }
1659                     perms.add(perm);
1660                     XmlUtils.skipCurrentTag(parser);
1661 
1662                 } else if ("library".equals(name)) {
1663                     String lname = parser.getAttributeValue(null, "name");
1664                     String lfile = parser.getAttributeValue(null, "file");
1665                     if (lname == null) {
1666                         Slog.w(TAG, "<library> without name at "
1667                                 + parser.getPositionDescription());
1668                     } else if (lfile == null) {
1669                         Slog.w(TAG, "<library> without file at "
1670                                 + parser.getPositionDescription());
1671                     } else {
1672                         //Log.i(TAG, "Got library " + lname + " in " + lfile);
1673                         mSharedLibraries.put(lname, new SharedLibraryEntry(lfile, null));
1674                     }
1675                     XmlUtils.skipCurrentTag(parser);
1676                     continue;
1677 
1678                 } else if ("feature".equals(name)) {
1679                     String fname = parser.getAttributeValue(null, "name");
1680                     if (fname == null) {
1681                         Slog.w(TAG, "<feature> without name at "
1682                                 + parser.getPositionDescription());
1683                     } else {
1684                         //Log.i(TAG, "Got feature " + fname);
1685                         FeatureInfo fi = new FeatureInfo();
1686                         fi.name = fname;
1687                         mAvailableFeatures.put(fname, fi);
1688                     }
1689                     XmlUtils.skipCurrentTag(parser);
1690                     continue;
1691 
1692                 } else {
1693                     XmlUtils.skipCurrentTag(parser);
1694                     continue;
1695                 }
1696 
1697             }
1698             permReader.close();
1699         } catch (XmlPullParserException e) {
1700             Slog.w(TAG, "Got execption parsing permissions.", e);
1701         } catch (IOException e) {
1702             Slog.w(TAG, "Got execption parsing permissions.", e);
1703         }
1704     }
1705 
readPermission(XmlPullParser parser, String name)1706     void readPermission(XmlPullParser parser, String name)
1707             throws IOException, XmlPullParserException {
1708 
1709         name = name.intern();
1710 
1711         BasePermission bp = mSettings.mPermissions.get(name);
1712         if (bp == null) {
1713             bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
1714             mSettings.mPermissions.put(name, bp);
1715         }
1716         int outerDepth = parser.getDepth();
1717         int type;
1718         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1719                && (type != XmlPullParser.END_TAG
1720                        || parser.getDepth() > outerDepth)) {
1721             if (type == XmlPullParser.END_TAG
1722                     || type == XmlPullParser.TEXT) {
1723                 continue;
1724             }
1725 
1726             String tagName = parser.getName();
1727             if ("group".equals(tagName)) {
1728                 String gidStr = parser.getAttributeValue(null, "gid");
1729                 if (gidStr != null) {
1730                     int gid = Process.getGidForName(gidStr);
1731                     bp.gids = appendInt(bp.gids, gid);
1732                 } else {
1733                     Slog.w(TAG, "<group> without gid at "
1734                             + parser.getPositionDescription());
1735                 }
1736             }
1737             XmlUtils.skipCurrentTag(parser);
1738         }
1739     }
1740 
appendInts(int[] cur, int[] add)1741     static int[] appendInts(int[] cur, int[] add) {
1742         if (add == null) return cur;
1743         if (cur == null) return add;
1744         final int N = add.length;
1745         for (int i=0; i<N; i++) {
1746             cur = appendInt(cur, add[i]);
1747         }
1748         return cur;
1749     }
1750 
removeInts(int[] cur, int[] rem)1751     static int[] removeInts(int[] cur, int[] rem) {
1752         if (rem == null) return cur;
1753         if (cur == null) return cur;
1754         final int N = rem.length;
1755         for (int i=0; i<N; i++) {
1756             cur = removeInt(cur, rem[i]);
1757         }
1758         return cur;
1759     }
1760 
generatePackageInfo(PackageParser.Package p, int flags, int userId)1761     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1762         if (!sUserManager.exists(userId)) return null;
1763         PackageInfo pi;
1764         final PackageSetting ps = (PackageSetting) p.mExtras;
1765         if (ps == null) {
1766             return null;
1767         }
1768         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1769         final PackageUserState state = ps.readUserState(userId);
1770         return PackageParser.generatePackageInfo(p, gp.gids, flags,
1771                 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1772                 state, userId);
1773     }
1774 
isPackageAvailable(String packageName, int userId)1775     public boolean isPackageAvailable(String packageName, int userId) {
1776         if (!sUserManager.exists(userId)) return false;
1777         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available");
1778         synchronized (mPackages) {
1779             PackageParser.Package p = mPackages.get(packageName);
1780             if (p != null) {
1781                 final PackageSetting ps = (PackageSetting) p.mExtras;
1782                 if (ps != null) {
1783                     final PackageUserState state = ps.readUserState(userId);
1784                     if (state != null) {
1785                         return PackageParser.isAvailable(state);
1786                     }
1787                 }
1788             }
1789         }
1790         return false;
1791     }
1792 
1793     @Override
getPackageInfo(String packageName, int flags, int userId)1794     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1795         if (!sUserManager.exists(userId)) return null;
1796         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
1797         // reader
1798         synchronized (mPackages) {
1799             PackageParser.Package p = mPackages.get(packageName);
1800             if (DEBUG_PACKAGE_INFO)
1801                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1802             if (p != null) {
1803                 return generatePackageInfo(p, flags, userId);
1804             }
1805             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1806                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1807             }
1808         }
1809         return null;
1810     }
1811 
currentToCanonicalPackageNames(String[] names)1812     public String[] currentToCanonicalPackageNames(String[] names) {
1813         String[] out = new String[names.length];
1814         // reader
1815         synchronized (mPackages) {
1816             for (int i=names.length-1; i>=0; i--) {
1817                 PackageSetting ps = mSettings.mPackages.get(names[i]);
1818                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1819             }
1820         }
1821         return out;
1822     }
1823 
canonicalToCurrentPackageNames(String[] names)1824     public String[] canonicalToCurrentPackageNames(String[] names) {
1825         String[] out = new String[names.length];
1826         // reader
1827         synchronized (mPackages) {
1828             for (int i=names.length-1; i>=0; i--) {
1829                 String cur = mSettings.mRenamedPackages.get(names[i]);
1830                 out[i] = cur != null ? cur : names[i];
1831             }
1832         }
1833         return out;
1834     }
1835 
1836     @Override
getPackageUid(String packageName, int userId)1837     public int getPackageUid(String packageName, int userId) {
1838         if (!sUserManager.exists(userId)) return -1;
1839         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
1840         // reader
1841         synchronized (mPackages) {
1842             PackageParser.Package p = mPackages.get(packageName);
1843             if(p != null) {
1844                 return UserHandle.getUid(userId, p.applicationInfo.uid);
1845             }
1846             PackageSetting ps = mSettings.mPackages.get(packageName);
1847             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1848                 return -1;
1849             }
1850             p = ps.pkg;
1851             return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1852         }
1853     }
1854 
1855     @Override
getPackageGids(String packageName)1856     public int[] getPackageGids(String packageName) {
1857         // reader
1858         synchronized (mPackages) {
1859             PackageParser.Package p = mPackages.get(packageName);
1860             if (DEBUG_PACKAGE_INFO)
1861                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1862             if (p != null) {
1863                 final PackageSetting ps = (PackageSetting)p.mExtras;
1864                 return ps.getGids();
1865             }
1866         }
1867         // stupid thing to indicate an error.
1868         return new int[0];
1869     }
1870 
generatePermissionInfo( BasePermission bp, int flags)1871     static final PermissionInfo generatePermissionInfo(
1872             BasePermission bp, int flags) {
1873         if (bp.perm != null) {
1874             return PackageParser.generatePermissionInfo(bp.perm, flags);
1875         }
1876         PermissionInfo pi = new PermissionInfo();
1877         pi.name = bp.name;
1878         pi.packageName = bp.sourcePackage;
1879         pi.nonLocalizedLabel = bp.name;
1880         pi.protectionLevel = bp.protectionLevel;
1881         return pi;
1882     }
1883 
getPermissionInfo(String name, int flags)1884     public PermissionInfo getPermissionInfo(String name, int flags) {
1885         // reader
1886         synchronized (mPackages) {
1887             final BasePermission p = mSettings.mPermissions.get(name);
1888             if (p != null) {
1889                 return generatePermissionInfo(p, flags);
1890             }
1891             return null;
1892         }
1893     }
1894 
queryPermissionsByGroup(String group, int flags)1895     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
1896         // reader
1897         synchronized (mPackages) {
1898             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
1899             for (BasePermission p : mSettings.mPermissions.values()) {
1900                 if (group == null) {
1901                     if (p.perm == null || p.perm.info.group == null) {
1902                         out.add(generatePermissionInfo(p, flags));
1903                     }
1904                 } else {
1905                     if (p.perm != null && group.equals(p.perm.info.group)) {
1906                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
1907                     }
1908                 }
1909             }
1910 
1911             if (out.size() > 0) {
1912                 return out;
1913             }
1914             return mPermissionGroups.containsKey(group) ? out : null;
1915         }
1916     }
1917 
getPermissionGroupInfo(String name, int flags)1918     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
1919         // reader
1920         synchronized (mPackages) {
1921             return PackageParser.generatePermissionGroupInfo(
1922                     mPermissionGroups.get(name), flags);
1923         }
1924     }
1925 
getAllPermissionGroups(int flags)1926     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1927         // reader
1928         synchronized (mPackages) {
1929             final int N = mPermissionGroups.size();
1930             ArrayList<PermissionGroupInfo> out
1931                     = new ArrayList<PermissionGroupInfo>(N);
1932             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
1933                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
1934             }
1935             return out;
1936         }
1937     }
1938 
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int userId)1939     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
1940             int userId) {
1941         if (!sUserManager.exists(userId)) return null;
1942         PackageSetting ps = mSettings.mPackages.get(packageName);
1943         if (ps != null) {
1944             if (ps.pkg == null) {
1945                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
1946                         flags, userId);
1947                 if (pInfo != null) {
1948                     return pInfo.applicationInfo;
1949                 }
1950                 return null;
1951             }
1952             return PackageParser.generateApplicationInfo(ps.pkg, flags,
1953                     ps.readUserState(userId), userId);
1954         }
1955         return null;
1956     }
1957 
generatePackageInfoFromSettingsLPw(String packageName, int flags, int userId)1958     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
1959             int userId) {
1960         if (!sUserManager.exists(userId)) return null;
1961         PackageSetting ps = mSettings.mPackages.get(packageName);
1962         if (ps != null) {
1963             PackageParser.Package pkg = ps.pkg;
1964             if (pkg == null) {
1965                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
1966                     return null;
1967                 }
1968                 pkg = new PackageParser.Package(packageName);
1969                 pkg.applicationInfo.packageName = packageName;
1970                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
1971                 pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
1972                 pkg.applicationInfo.sourceDir = ps.codePathString;
1973                 pkg.applicationInfo.dataDir =
1974                         getDataPathForPackage(packageName, 0).getPath();
1975                 pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
1976             }
1977             return generatePackageInfo(pkg, flags, userId);
1978         }
1979         return null;
1980     }
1981 
1982     @Override
getApplicationInfo(String packageName, int flags, int userId)1983     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
1984         if (!sUserManager.exists(userId)) return null;
1985         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
1986         // writer
1987         synchronized (mPackages) {
1988             PackageParser.Package p = mPackages.get(packageName);
1989             if (DEBUG_PACKAGE_INFO) Log.v(
1990                     TAG, "getApplicationInfo " + packageName
1991                     + ": " + p);
1992             if (p != null) {
1993                 PackageSetting ps = mSettings.mPackages.get(packageName);
1994                 if (ps == null) return null;
1995                 // Note: isEnabledLP() does not apply here - always return info
1996                 return PackageParser.generateApplicationInfo(
1997                         p, flags, ps.readUserState(userId), userId);
1998             }
1999             if ("android".equals(packageName)||"system".equals(packageName)) {
2000                 return mAndroidApplication;
2001             }
2002             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2003                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2004             }
2005         }
2006         return null;
2007     }
2008 
2009 
freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer)2010     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
2011         mContext.enforceCallingOrSelfPermission(
2012                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2013         // Queue up an async operation since clearing cache may take a little while.
2014         mHandler.post(new Runnable() {
2015             public void run() {
2016                 mHandler.removeCallbacks(this);
2017                 int retCode = -1;
2018                 synchronized (mInstallLock) {
2019                     retCode = mInstaller.freeCache(freeStorageSize);
2020                     if (retCode < 0) {
2021                         Slog.w(TAG, "Couldn't clear application caches");
2022                     }
2023                 }
2024                 if (observer != null) {
2025                     try {
2026                         observer.onRemoveCompleted(null, (retCode >= 0));
2027                     } catch (RemoteException e) {
2028                         Slog.w(TAG, "RemoveException when invoking call back");
2029                     }
2030                 }
2031             }
2032         });
2033     }
2034 
freeStorage(final long freeStorageSize, final IntentSender pi)2035     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
2036         mContext.enforceCallingOrSelfPermission(
2037                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2038         // Queue up an async operation since clearing cache may take a little while.
2039         mHandler.post(new Runnable() {
2040             public void run() {
2041                 mHandler.removeCallbacks(this);
2042                 int retCode = -1;
2043                 synchronized (mInstallLock) {
2044                     retCode = mInstaller.freeCache(freeStorageSize);
2045                     if (retCode < 0) {
2046                         Slog.w(TAG, "Couldn't clear application caches");
2047                     }
2048                 }
2049                 if(pi != null) {
2050                     try {
2051                         // Callback via pending intent
2052                         int code = (retCode >= 0) ? 1 : 0;
2053                         pi.sendIntent(null, code, null,
2054                                 null, null);
2055                     } catch (SendIntentException e1) {
2056                         Slog.i(TAG, "Failed to send pending intent");
2057                     }
2058                 }
2059             }
2060         });
2061     }
2062 
2063     @Override
getActivityInfo(ComponentName component, int flags, int userId)2064     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2065         if (!sUserManager.exists(userId)) return null;
2066         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
2067         synchronized (mPackages) {
2068             PackageParser.Activity a = mActivities.mActivities.get(component);
2069 
2070             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2071             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2072                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2073                 if (ps == null) return null;
2074                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2075                         userId);
2076             }
2077             if (mResolveComponentName.equals(component)) {
2078                 return mResolveActivity;
2079             }
2080         }
2081         return null;
2082     }
2083 
2084     @Override
getReceiverInfo(ComponentName component, int flags, int userId)2085     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2086         if (!sUserManager.exists(userId)) return null;
2087         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
2088         synchronized (mPackages) {
2089             PackageParser.Activity a = mReceivers.mActivities.get(component);
2090             if (DEBUG_PACKAGE_INFO) Log.v(
2091                 TAG, "getReceiverInfo " + component + ": " + a);
2092             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2093                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2094                 if (ps == null) return null;
2095                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2096                         userId);
2097             }
2098         }
2099         return null;
2100     }
2101 
2102     @Override
getServiceInfo(ComponentName component, int flags, int userId)2103     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2104         if (!sUserManager.exists(userId)) return null;
2105         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
2106         synchronized (mPackages) {
2107             PackageParser.Service s = mServices.mServices.get(component);
2108             if (DEBUG_PACKAGE_INFO) Log.v(
2109                 TAG, "getServiceInfo " + component + ": " + s);
2110             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2111                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2112                 if (ps == null) return null;
2113                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2114                         userId);
2115             }
2116         }
2117         return null;
2118     }
2119 
2120     @Override
getProviderInfo(ComponentName component, int flags, int userId)2121     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2122         if (!sUserManager.exists(userId)) return null;
2123         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
2124         synchronized (mPackages) {
2125             PackageParser.Provider p = mProviders.mProviders.get(component);
2126             if (DEBUG_PACKAGE_INFO) Log.v(
2127                 TAG, "getProviderInfo " + component + ": " + p);
2128             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2129                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2130                 if (ps == null) return null;
2131                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2132                         userId);
2133             }
2134         }
2135         return null;
2136     }
2137 
getSystemSharedLibraryNames()2138     public String[] getSystemSharedLibraryNames() {
2139         Set<String> libSet;
2140         synchronized (mPackages) {
2141             libSet = mSharedLibraries.keySet();
2142             int size = libSet.size();
2143             if (size > 0) {
2144                 String[] libs = new String[size];
2145                 libSet.toArray(libs);
2146                 return libs;
2147             }
2148         }
2149         return null;
2150     }
2151 
getSystemAvailableFeatures()2152     public FeatureInfo[] getSystemAvailableFeatures() {
2153         Collection<FeatureInfo> featSet;
2154         synchronized (mPackages) {
2155             featSet = mAvailableFeatures.values();
2156             int size = featSet.size();
2157             if (size > 0) {
2158                 FeatureInfo[] features = new FeatureInfo[size+1];
2159                 featSet.toArray(features);
2160                 FeatureInfo fi = new FeatureInfo();
2161                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2162                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
2163                 features[size] = fi;
2164                 return features;
2165             }
2166         }
2167         return null;
2168     }
2169 
hasSystemFeature(String name)2170     public boolean hasSystemFeature(String name) {
2171         synchronized (mPackages) {
2172             return mAvailableFeatures.containsKey(name);
2173         }
2174     }
2175 
checkValidCaller(int uid, int userId)2176     private void checkValidCaller(int uid, int userId) {
2177         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2178             return;
2179 
2180         throw new SecurityException("Caller uid=" + uid
2181                 + " is not privileged to communicate with user=" + userId);
2182     }
2183 
checkPermission(String permName, String pkgName)2184     public int checkPermission(String permName, String pkgName) {
2185         synchronized (mPackages) {
2186             PackageParser.Package p = mPackages.get(pkgName);
2187             if (p != null && p.mExtras != null) {
2188                 PackageSetting ps = (PackageSetting)p.mExtras;
2189                 if (ps.sharedUser != null) {
2190                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
2191                         return PackageManager.PERMISSION_GRANTED;
2192                     }
2193                 } else if (ps.grantedPermissions.contains(permName)) {
2194                     return PackageManager.PERMISSION_GRANTED;
2195                 }
2196             }
2197         }
2198         return PackageManager.PERMISSION_DENIED;
2199     }
2200 
checkUidPermission(String permName, int uid)2201     public int checkUidPermission(String permName, int uid) {
2202         synchronized (mPackages) {
2203             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2204             if (obj != null) {
2205                 GrantedPermissions gp = (GrantedPermissions)obj;
2206                 if (gp.grantedPermissions.contains(permName)) {
2207                     return PackageManager.PERMISSION_GRANTED;
2208                 }
2209             } else {
2210                 HashSet<String> perms = mSystemPermissions.get(uid);
2211                 if (perms != null && perms.contains(permName)) {
2212                     return PackageManager.PERMISSION_GRANTED;
2213                 }
2214             }
2215         }
2216         return PackageManager.PERMISSION_DENIED;
2217     }
2218 
2219     /**
2220      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2221      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2222      * @param message the message to log on security exception
2223      * @return
2224      */
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, String message)2225     private void enforceCrossUserPermission(int callingUid, int userId,
2226             boolean requireFullPermission, String message) {
2227         if (userId < 0) {
2228             throw new IllegalArgumentException("Invalid userId " + userId);
2229         }
2230         if (userId == UserHandle.getUserId(callingUid)) return;
2231         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2232             if (requireFullPermission) {
2233                 mContext.enforceCallingOrSelfPermission(
2234                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2235             } else {
2236                 try {
2237                     mContext.enforceCallingOrSelfPermission(
2238                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2239                 } catch (SecurityException se) {
2240                     mContext.enforceCallingOrSelfPermission(
2241                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2242                 }
2243             }
2244         }
2245     }
2246 
findPermissionTreeLP(String permName)2247     private BasePermission findPermissionTreeLP(String permName) {
2248         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2249             if (permName.startsWith(bp.name) &&
2250                     permName.length() > bp.name.length() &&
2251                     permName.charAt(bp.name.length()) == '.') {
2252                 return bp;
2253             }
2254         }
2255         return null;
2256     }
2257 
checkPermissionTreeLP(String permName)2258     private BasePermission checkPermissionTreeLP(String permName) {
2259         if (permName != null) {
2260             BasePermission bp = findPermissionTreeLP(permName);
2261             if (bp != null) {
2262                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2263                     return bp;
2264                 }
2265                 throw new SecurityException("Calling uid "
2266                         + Binder.getCallingUid()
2267                         + " is not allowed to add to permission tree "
2268                         + bp.name + " owned by uid " + bp.uid);
2269             }
2270         }
2271         throw new SecurityException("No permission tree found for " + permName);
2272     }
2273 
compareStrings(CharSequence s1, CharSequence s2)2274     static boolean compareStrings(CharSequence s1, CharSequence s2) {
2275         if (s1 == null) {
2276             return s2 == null;
2277         }
2278         if (s2 == null) {
2279             return false;
2280         }
2281         if (s1.getClass() != s2.getClass()) {
2282             return false;
2283         }
2284         return s1.equals(s2);
2285     }
2286 
comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2)2287     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2288         if (pi1.icon != pi2.icon) return false;
2289         if (pi1.logo != pi2.logo) return false;
2290         if (pi1.protectionLevel != pi2.protectionLevel) return false;
2291         if (!compareStrings(pi1.name, pi2.name)) return false;
2292         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2293         // We'll take care of setting this one.
2294         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2295         // These are not currently stored in settings.
2296         //if (!compareStrings(pi1.group, pi2.group)) return false;
2297         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2298         //if (pi1.labelRes != pi2.labelRes) return false;
2299         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2300         return true;
2301     }
2302 
addPermissionLocked(PermissionInfo info, boolean async)2303     boolean addPermissionLocked(PermissionInfo info, boolean async) {
2304         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2305             throw new SecurityException("Label must be specified in permission");
2306         }
2307         BasePermission tree = checkPermissionTreeLP(info.name);
2308         BasePermission bp = mSettings.mPermissions.get(info.name);
2309         boolean added = bp == null;
2310         boolean changed = true;
2311         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2312         if (added) {
2313             bp = new BasePermission(info.name, tree.sourcePackage,
2314                     BasePermission.TYPE_DYNAMIC);
2315         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2316             throw new SecurityException(
2317                     "Not allowed to modify non-dynamic permission "
2318                     + info.name);
2319         } else {
2320             if (bp.protectionLevel == fixedLevel
2321                     && bp.perm.owner.equals(tree.perm.owner)
2322                     && bp.uid == tree.uid
2323                     && comparePermissionInfos(bp.perm.info, info)) {
2324                 changed = false;
2325             }
2326         }
2327         bp.protectionLevel = fixedLevel;
2328         info = new PermissionInfo(info);
2329         info.protectionLevel = fixedLevel;
2330         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2331         bp.perm.info.packageName = tree.perm.info.packageName;
2332         bp.uid = tree.uid;
2333         if (added) {
2334             mSettings.mPermissions.put(info.name, bp);
2335         }
2336         if (changed) {
2337             if (!async) {
2338                 mSettings.writeLPr();
2339             } else {
2340                 scheduleWriteSettingsLocked();
2341             }
2342         }
2343         return added;
2344     }
2345 
addPermission(PermissionInfo info)2346     public boolean addPermission(PermissionInfo info) {
2347         synchronized (mPackages) {
2348             return addPermissionLocked(info, false);
2349         }
2350     }
2351 
addPermissionAsync(PermissionInfo info)2352     public boolean addPermissionAsync(PermissionInfo info) {
2353         synchronized (mPackages) {
2354             return addPermissionLocked(info, true);
2355         }
2356     }
2357 
removePermission(String name)2358     public void removePermission(String name) {
2359         synchronized (mPackages) {
2360             checkPermissionTreeLP(name);
2361             BasePermission bp = mSettings.mPermissions.get(name);
2362             if (bp != null) {
2363                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2364                     throw new SecurityException(
2365                             "Not allowed to modify non-dynamic permission "
2366                             + name);
2367                 }
2368                 mSettings.mPermissions.remove(name);
2369                 mSettings.writeLPr();
2370             }
2371         }
2372     }
2373 
checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp)2374     private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2375         int index = pkg.requestedPermissions.indexOf(bp.name);
2376         if (index == -1) {
2377             throw new SecurityException("Package " + pkg.packageName
2378                     + " has not requested permission " + bp.name);
2379         }
2380         boolean isNormal =
2381                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2382                         == PermissionInfo.PROTECTION_NORMAL);
2383         boolean isDangerous =
2384                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2385                         == PermissionInfo.PROTECTION_DANGEROUS);
2386         boolean isDevelopment =
2387                 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2388 
2389         if (!isNormal && !isDangerous && !isDevelopment) {
2390             throw new SecurityException("Permission " + bp.name
2391                     + " is not a changeable permission type");
2392         }
2393 
2394         if (isNormal || isDangerous) {
2395             if (pkg.requestedPermissionsRequired.get(index)) {
2396                 throw new SecurityException("Can't change " + bp.name
2397                         + ". It is required by the application");
2398             }
2399         }
2400     }
2401 
grantPermission(String packageName, String permissionName)2402     public void grantPermission(String packageName, String permissionName) {
2403         mContext.enforceCallingOrSelfPermission(
2404                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2405         synchronized (mPackages) {
2406             final PackageParser.Package pkg = mPackages.get(packageName);
2407             if (pkg == null) {
2408                 throw new IllegalArgumentException("Unknown package: " + packageName);
2409             }
2410             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2411             if (bp == null) {
2412                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2413             }
2414 
2415             checkGrantRevokePermissions(pkg, bp);
2416 
2417             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2418             if (ps == null) {
2419                 return;
2420             }
2421             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2422             if (gp.grantedPermissions.add(permissionName)) {
2423                 if (ps.haveGids) {
2424                     gp.gids = appendInts(gp.gids, bp.gids);
2425                 }
2426                 mSettings.writeLPr();
2427             }
2428         }
2429     }
2430 
revokePermission(String packageName, String permissionName)2431     public void revokePermission(String packageName, String permissionName) {
2432         int changedAppId = -1;
2433 
2434         synchronized (mPackages) {
2435             final PackageParser.Package pkg = mPackages.get(packageName);
2436             if (pkg == null) {
2437                 throw new IllegalArgumentException("Unknown package: " + packageName);
2438             }
2439             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2440                 mContext.enforceCallingOrSelfPermission(
2441                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2442             }
2443             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2444             if (bp == null) {
2445                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2446             }
2447 
2448             checkGrantRevokePermissions(pkg, bp);
2449 
2450             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2451             if (ps == null) {
2452                 return;
2453             }
2454             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2455             if (gp.grantedPermissions.remove(permissionName)) {
2456                 gp.grantedPermissions.remove(permissionName);
2457                 if (ps.haveGids) {
2458                     gp.gids = removeInts(gp.gids, bp.gids);
2459                 }
2460                 mSettings.writeLPr();
2461                 changedAppId = ps.appId;
2462             }
2463         }
2464 
2465         if (changedAppId >= 0) {
2466             // We changed the perm on someone, kill its processes.
2467             IActivityManager am = ActivityManagerNative.getDefault();
2468             if (am != null) {
2469                 final int callingUserId = UserHandle.getCallingUserId();
2470                 final long ident = Binder.clearCallingIdentity();
2471                 try {
2472                     //XXX we should only revoke for the calling user's app permissions,
2473                     // but for now we impact all users.
2474                     //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2475                     //        "revoke " + permissionName);
2476                     int[] users = sUserManager.getUserIds();
2477                     for (int user : users) {
2478                         am.killUid(UserHandle.getUid(user, changedAppId),
2479                                 "revoke " + permissionName);
2480                     }
2481                 } catch (RemoteException e) {
2482                 } finally {
2483                     Binder.restoreCallingIdentity(ident);
2484                 }
2485             }
2486         }
2487     }
2488 
isProtectedBroadcast(String actionName)2489     public boolean isProtectedBroadcast(String actionName) {
2490         synchronized (mPackages) {
2491             return mProtectedBroadcasts.contains(actionName);
2492         }
2493     }
2494 
checkSignatures(String pkg1, String pkg2)2495     public int checkSignatures(String pkg1, String pkg2) {
2496         synchronized (mPackages) {
2497             final PackageParser.Package p1 = mPackages.get(pkg1);
2498             final PackageParser.Package p2 = mPackages.get(pkg2);
2499             if (p1 == null || p1.mExtras == null
2500                     || p2 == null || p2.mExtras == null) {
2501                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2502             }
2503             return compareSignatures(p1.mSignatures, p2.mSignatures);
2504         }
2505     }
2506 
checkUidSignatures(int uid1, int uid2)2507     public int checkUidSignatures(int uid1, int uid2) {
2508         // Map to base uids.
2509         uid1 = UserHandle.getAppId(uid1);
2510         uid2 = UserHandle.getAppId(uid2);
2511         // reader
2512         synchronized (mPackages) {
2513             Signature[] s1;
2514             Signature[] s2;
2515             Object obj = mSettings.getUserIdLPr(uid1);
2516             if (obj != null) {
2517                 if (obj instanceof SharedUserSetting) {
2518                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2519                 } else if (obj instanceof PackageSetting) {
2520                     s1 = ((PackageSetting)obj).signatures.mSignatures;
2521                 } else {
2522                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2523                 }
2524             } else {
2525                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2526             }
2527             obj = mSettings.getUserIdLPr(uid2);
2528             if (obj != null) {
2529                 if (obj instanceof SharedUserSetting) {
2530                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2531                 } else if (obj instanceof PackageSetting) {
2532                     s2 = ((PackageSetting)obj).signatures.mSignatures;
2533                 } else {
2534                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2535                 }
2536             } else {
2537                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2538             }
2539             return compareSignatures(s1, s2);
2540         }
2541     }
2542 
compareSignatures(Signature[] s1, Signature[] s2)2543     static int compareSignatures(Signature[] s1, Signature[] s2) {
2544         if (s1 == null) {
2545             return s2 == null
2546                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
2547                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2548         }
2549         if (s2 == null) {
2550             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2551         }
2552         HashSet<Signature> set1 = new HashSet<Signature>();
2553         for (Signature sig : s1) {
2554             set1.add(sig);
2555         }
2556         HashSet<Signature> set2 = new HashSet<Signature>();
2557         for (Signature sig : s2) {
2558             set2.add(sig);
2559         }
2560         // Make sure s2 contains all signatures in s1.
2561         if (set1.equals(set2)) {
2562             return PackageManager.SIGNATURE_MATCH;
2563         }
2564         return PackageManager.SIGNATURE_NO_MATCH;
2565     }
2566 
getPackagesForUid(int uid)2567     public String[] getPackagesForUid(int uid) {
2568         uid = UserHandle.getAppId(uid);
2569         // reader
2570         synchronized (mPackages) {
2571             Object obj = mSettings.getUserIdLPr(uid);
2572             if (obj instanceof SharedUserSetting) {
2573                 final SharedUserSetting sus = (SharedUserSetting) obj;
2574                 final int N = sus.packages.size();
2575                 final String[] res = new String[N];
2576                 final Iterator<PackageSetting> it = sus.packages.iterator();
2577                 int i = 0;
2578                 while (it.hasNext()) {
2579                     res[i++] = it.next().name;
2580                 }
2581                 return res;
2582             } else if (obj instanceof PackageSetting) {
2583                 final PackageSetting ps = (PackageSetting) obj;
2584                 return new String[] { ps.name };
2585             }
2586         }
2587         return null;
2588     }
2589 
getNameForUid(int uid)2590     public String getNameForUid(int uid) {
2591         // reader
2592         synchronized (mPackages) {
2593             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2594             if (obj instanceof SharedUserSetting) {
2595                 final SharedUserSetting sus = (SharedUserSetting) obj;
2596                 return sus.name + ":" + sus.userId;
2597             } else if (obj instanceof PackageSetting) {
2598                 final PackageSetting ps = (PackageSetting) obj;
2599                 return ps.name;
2600             }
2601         }
2602         return null;
2603     }
2604 
getUidForSharedUser(String sharedUserName)2605     public int getUidForSharedUser(String sharedUserName) {
2606         if(sharedUserName == null) {
2607             return -1;
2608         }
2609         // reader
2610         synchronized (mPackages) {
2611             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2612             if (suid == null) {
2613                 return -1;
2614             }
2615             return suid.userId;
2616         }
2617     }
2618 
getFlagsForUid(int uid)2619     public int getFlagsForUid(int uid) {
2620         synchronized (mPackages) {
2621             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2622             if (obj instanceof SharedUserSetting) {
2623                 final SharedUserSetting sus = (SharedUserSetting) obj;
2624                 return sus.pkgFlags;
2625             } else if (obj instanceof PackageSetting) {
2626                 final PackageSetting ps = (PackageSetting) obj;
2627                 return ps.pkgFlags;
2628             }
2629         }
2630         return 0;
2631     }
2632 
2633     @Override
resolveIntent(Intent intent, String resolvedType, int flags, int userId)2634     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2635             int flags, int userId) {
2636         if (!sUserManager.exists(userId)) return null;
2637         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
2638         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2639         return chooseBestActivity(intent, resolvedType, flags, query, userId);
2640     }
2641 
2642     @Override
setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)2643     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
2644             IntentFilter filter, int match, ComponentName activity) {
2645         final int userId = UserHandle.getCallingUserId();
2646         if (DEBUG_PREFERRED) {
2647             Log.v(TAG, "setLastChosenActivity intent=" + intent
2648                 + " resolvedType=" + resolvedType
2649                 + " flags=" + flags
2650                 + " filter=" + filter
2651                 + " match=" + match
2652                 + " activity=" + activity);
2653             filter.dump(new PrintStreamPrinter(System.out), "    ");
2654         }
2655         intent.setComponent(null);
2656         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2657         // Find any earlier preferred or last chosen entries and nuke them
2658         findPreferredActivity(intent, resolvedType,
2659                 flags, query, 0, false, true, false, userId);
2660         // Add the new activity as the last chosen for this filter
2661         addPreferredActivityInternal(filter, match, null, activity, false, userId);
2662     }
2663 
2664     @Override
getLastChosenActivity(Intent intent, String resolvedType, int flags)2665     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
2666         final int userId = UserHandle.getCallingUserId();
2667         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
2668         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2669         return findPreferredActivity(intent, resolvedType, flags, query, 0,
2670                 false, false, false, userId);
2671     }
2672 
chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int userId)2673     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
2674             int flags, List<ResolveInfo> query, int userId) {
2675         if (query != null) {
2676             final int N = query.size();
2677             if (N == 1) {
2678                 return query.get(0);
2679             } else if (N > 1) {
2680                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
2681                 // If there is more than one activity with the same priority,
2682                 // then let the user decide between them.
2683                 ResolveInfo r0 = query.get(0);
2684                 ResolveInfo r1 = query.get(1);
2685                 if (DEBUG_INTENT_MATCHING || debug) {
2686                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
2687                             + r1.activityInfo.name + "=" + r1.priority);
2688                 }
2689                 // If the first activity has a higher priority, or a different
2690                 // default, then it is always desireable to pick it.
2691                 if (r0.priority != r1.priority
2692                         || r0.preferredOrder != r1.preferredOrder
2693                         || r0.isDefault != r1.isDefault) {
2694                     return query.get(0);
2695                 }
2696                 // If we have saved a preference for a preferred activity for
2697                 // this Intent, use that.
2698                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
2699                         flags, query, r0.priority, true, false, debug, userId);
2700                 if (ri != null) {
2701                     return ri;
2702                 }
2703                 if (userId != 0) {
2704                     ri = new ResolveInfo(mResolveInfo);
2705                     ri.activityInfo = new ActivityInfo(ri.activityInfo);
2706                     ri.activityInfo.applicationInfo = new ApplicationInfo(
2707                             ri.activityInfo.applicationInfo);
2708                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
2709                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
2710                     return ri;
2711                 }
2712                 return mResolveInfo;
2713             }
2714         }
2715         return null;
2716     }
2717 
findPreferredActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)2718     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
2719             List<ResolveInfo> query, int priority, boolean always,
2720             boolean removeMatches, boolean debug, int userId) {
2721         if (!sUserManager.exists(userId)) return null;
2722         // writer
2723         synchronized (mPackages) {
2724             if (intent.getSelector() != null) {
2725                 intent = intent.getSelector();
2726             }
2727             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
2728             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
2729             // Get the list of preferred activities that handle the intent
2730             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
2731             List<PreferredActivity> prefs = pir != null
2732                     ? pir.queryIntent(intent, resolvedType,
2733                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
2734                     : null;
2735             if (prefs != null && prefs.size() > 0) {
2736                 // First figure out how good the original match set is.
2737                 // We will only allow preferred activities that came
2738                 // from the same match quality.
2739                 int match = 0;
2740 
2741                 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
2742 
2743                 final int N = query.size();
2744                 for (int j=0; j<N; j++) {
2745                     final ResolveInfo ri = query.get(j);
2746                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
2747                             + ": 0x" + Integer.toHexString(match));
2748                     if (ri.match > match) {
2749                         match = ri.match;
2750                     }
2751                 }
2752 
2753                 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
2754                         + Integer.toHexString(match));
2755 
2756                 match &= IntentFilter.MATCH_CATEGORY_MASK;
2757                 final int M = prefs.size();
2758                 for (int i=0; i<M; i++) {
2759                     final PreferredActivity pa = prefs.get(i);
2760                     if (DEBUG_PREFERRED || debug) {
2761                         Slog.v(TAG, "Checking PreferredActivity ds="
2762                                 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
2763                                 + "\n  component=" + pa.mPref.mComponent);
2764                         pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
2765                     }
2766                     if (pa.mPref.mMatch != match) {
2767                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
2768                                 + Integer.toHexString(pa.mPref.mMatch));
2769                         continue;
2770                     }
2771                     // If it's not an "always" type preferred activity and that's what we're
2772                     // looking for, skip it.
2773                     if (always && !pa.mPref.mAlways) {
2774                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
2775                         continue;
2776                     }
2777                     final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
2778                             flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
2779                     if (DEBUG_PREFERRED || debug) {
2780                         Slog.v(TAG, "Found preferred activity:");
2781                         if (ai != null) {
2782                             ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
2783                         } else {
2784                             Slog.v(TAG, "  null");
2785                         }
2786                     }
2787                     if (ai == null) {
2788                         // This previously registered preferred activity
2789                         // component is no longer known.  Most likely an update
2790                         // to the app was installed and in the new version this
2791                         // component no longer exists.  Clean it up by removing
2792                         // it from the preferred activities list, and skip it.
2793                         Slog.w(TAG, "Removing dangling preferred activity: "
2794                                 + pa.mPref.mComponent);
2795                         pir.removeFilter(pa);
2796                         continue;
2797                     }
2798                     for (int j=0; j<N; j++) {
2799                         final ResolveInfo ri = query.get(j);
2800                         if (!ri.activityInfo.applicationInfo.packageName
2801                                 .equals(ai.applicationInfo.packageName)) {
2802                             continue;
2803                         }
2804                         if (!ri.activityInfo.name.equals(ai.name)) {
2805                             continue;
2806                         }
2807 
2808                         if (removeMatches) {
2809                             pir.removeFilter(pa);
2810                             if (DEBUG_PREFERRED) {
2811                                 Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
2812                             }
2813                             break;
2814                         }
2815 
2816                         // Okay we found a previously set preferred or last chosen app.
2817                         // If the result set is different from when this
2818                         // was created, we need to clear it and re-ask the
2819                         // user their preference, if we're looking for an "always" type entry.
2820                         if (always && !pa.mPref.sameSet(query, priority)) {
2821                             Slog.i(TAG, "Result set changed, dropping preferred activity for "
2822                                     + intent + " type " + resolvedType);
2823                             if (DEBUG_PREFERRED) {
2824                                 Slog.v(TAG, "Removing preferred activity since set changed "
2825                                         + pa.mPref.mComponent);
2826                             }
2827                             pir.removeFilter(pa);
2828                             // Re-add the filter as a "last chosen" entry (!always)
2829                             PreferredActivity lastChosen = new PreferredActivity(
2830                                     pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
2831                             pir.addFilter(lastChosen);
2832                             mSettings.writePackageRestrictionsLPr(userId);
2833                             return null;
2834                         }
2835 
2836                         // Yay! Either the set matched or we're looking for the last chosen
2837                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
2838                                 + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
2839                         mSettings.writePackageRestrictionsLPr(userId);
2840                         return ri;
2841                     }
2842                 }
2843             }
2844             mSettings.writePackageRestrictionsLPr(userId);
2845         }
2846         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
2847         return null;
2848     }
2849 
2850     @Override
queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)2851     public List<ResolveInfo> queryIntentActivities(Intent intent,
2852             String resolvedType, int flags, int userId) {
2853         if (!sUserManager.exists(userId)) return Collections.emptyList();
2854         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
2855         ComponentName comp = intent.getComponent();
2856         if (comp == null) {
2857             if (intent.getSelector() != null) {
2858                 intent = intent.getSelector();
2859                 comp = intent.getComponent();
2860             }
2861         }
2862 
2863         if (comp != null) {
2864             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2865             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
2866             if (ai != null) {
2867                 final ResolveInfo ri = new ResolveInfo();
2868                 ri.activityInfo = ai;
2869                 list.add(ri);
2870             }
2871             return list;
2872         }
2873 
2874         // reader
2875         synchronized (mPackages) {
2876             final String pkgName = intent.getPackage();
2877             if (pkgName == null) {
2878                 return mActivities.queryIntent(intent, resolvedType, flags, userId);
2879             }
2880             final PackageParser.Package pkg = mPackages.get(pkgName);
2881             if (pkg != null) {
2882                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
2883                         pkg.activities, userId);
2884             }
2885             return new ArrayList<ResolveInfo>();
2886         }
2887     }
2888 
2889     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)2890     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
2891             Intent[] specifics, String[] specificTypes, Intent intent,
2892             String resolvedType, int flags, int userId) {
2893         if (!sUserManager.exists(userId)) return Collections.emptyList();
2894         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
2895                 "query intent activity options");
2896         final String resultsAction = intent.getAction();
2897 
2898         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
2899                 | PackageManager.GET_RESOLVED_FILTER, userId);
2900 
2901         if (DEBUG_INTENT_MATCHING) {
2902             Log.v(TAG, "Query " + intent + ": " + results);
2903         }
2904 
2905         int specificsPos = 0;
2906         int N;
2907 
2908         // todo: note that the algorithm used here is O(N^2).  This
2909         // isn't a problem in our current environment, but if we start running
2910         // into situations where we have more than 5 or 10 matches then this
2911         // should probably be changed to something smarter...
2912 
2913         // First we go through and resolve each of the specific items
2914         // that were supplied, taking care of removing any corresponding
2915         // duplicate items in the generic resolve list.
2916         if (specifics != null) {
2917             for (int i=0; i<specifics.length; i++) {
2918                 final Intent sintent = specifics[i];
2919                 if (sintent == null) {
2920                     continue;
2921                 }
2922 
2923                 if (DEBUG_INTENT_MATCHING) {
2924                     Log.v(TAG, "Specific #" + i + ": " + sintent);
2925                 }
2926 
2927                 String action = sintent.getAction();
2928                 if (resultsAction != null && resultsAction.equals(action)) {
2929                     // If this action was explicitly requested, then don't
2930                     // remove things that have it.
2931                     action = null;
2932                 }
2933 
2934                 ResolveInfo ri = null;
2935                 ActivityInfo ai = null;
2936 
2937                 ComponentName comp = sintent.getComponent();
2938                 if (comp == null) {
2939                     ri = resolveIntent(
2940                         sintent,
2941                         specificTypes != null ? specificTypes[i] : null,
2942                             flags, userId);
2943                     if (ri == null) {
2944                         continue;
2945                     }
2946                     if (ri == mResolveInfo) {
2947                         // ACK!  Must do something better with this.
2948                     }
2949                     ai = ri.activityInfo;
2950                     comp = new ComponentName(ai.applicationInfo.packageName,
2951                             ai.name);
2952                 } else {
2953                     ai = getActivityInfo(comp, flags, userId);
2954                     if (ai == null) {
2955                         continue;
2956                     }
2957                 }
2958 
2959                 // Look for any generic query activities that are duplicates
2960                 // of this specific one, and remove them from the results.
2961                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
2962                 N = results.size();
2963                 int j;
2964                 for (j=specificsPos; j<N; j++) {
2965                     ResolveInfo sri = results.get(j);
2966                     if ((sri.activityInfo.name.equals(comp.getClassName())
2967                             && sri.activityInfo.applicationInfo.packageName.equals(
2968                                     comp.getPackageName()))
2969                         || (action != null && sri.filter.matchAction(action))) {
2970                         results.remove(j);
2971                         if (DEBUG_INTENT_MATCHING) Log.v(
2972                             TAG, "Removing duplicate item from " + j
2973                             + " due to specific " + specificsPos);
2974                         if (ri == null) {
2975                             ri = sri;
2976                         }
2977                         j--;
2978                         N--;
2979                     }
2980                 }
2981 
2982                 // Add this specific item to its proper place.
2983                 if (ri == null) {
2984                     ri = new ResolveInfo();
2985                     ri.activityInfo = ai;
2986                 }
2987                 results.add(specificsPos, ri);
2988                 ri.specificIndex = i;
2989                 specificsPos++;
2990             }
2991         }
2992 
2993         // Now we go through the remaining generic results and remove any
2994         // duplicate actions that are found here.
2995         N = results.size();
2996         for (int i=specificsPos; i<N-1; i++) {
2997             final ResolveInfo rii = results.get(i);
2998             if (rii.filter == null) {
2999                 continue;
3000             }
3001 
3002             // Iterate over all of the actions of this result's intent
3003             // filter...  typically this should be just one.
3004             final Iterator<String> it = rii.filter.actionsIterator();
3005             if (it == null) {
3006                 continue;
3007             }
3008             while (it.hasNext()) {
3009                 final String action = it.next();
3010                 if (resultsAction != null && resultsAction.equals(action)) {
3011                     // If this action was explicitly requested, then don't
3012                     // remove things that have it.
3013                     continue;
3014                 }
3015                 for (int j=i+1; j<N; j++) {
3016                     final ResolveInfo rij = results.get(j);
3017                     if (rij.filter != null && rij.filter.hasAction(action)) {
3018                         results.remove(j);
3019                         if (DEBUG_INTENT_MATCHING) Log.v(
3020                             TAG, "Removing duplicate item from " + j
3021                             + " due to action " + action + " at " + i);
3022                         j--;
3023                         N--;
3024                     }
3025                 }
3026             }
3027 
3028             // If the caller didn't request filter information, drop it now
3029             // so we don't have to marshall/unmarshall it.
3030             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3031                 rii.filter = null;
3032             }
3033         }
3034 
3035         // Filter out the caller activity if so requested.
3036         if (caller != null) {
3037             N = results.size();
3038             for (int i=0; i<N; i++) {
3039                 ActivityInfo ainfo = results.get(i).activityInfo;
3040                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
3041                         && caller.getClassName().equals(ainfo.name)) {
3042                     results.remove(i);
3043                     break;
3044                 }
3045             }
3046         }
3047 
3048         // If the caller didn't request filter information,
3049         // drop them now so we don't have to
3050         // marshall/unmarshall it.
3051         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3052             N = results.size();
3053             for (int i=0; i<N; i++) {
3054                 results.get(i).filter = null;
3055             }
3056         }
3057 
3058         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
3059         return results;
3060     }
3061 
3062     @Override
queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)3063     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
3064             int userId) {
3065         if (!sUserManager.exists(userId)) return Collections.emptyList();
3066         ComponentName comp = intent.getComponent();
3067         if (comp == null) {
3068             if (intent.getSelector() != null) {
3069                 intent = intent.getSelector();
3070                 comp = intent.getComponent();
3071             }
3072         }
3073         if (comp != null) {
3074             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3075             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
3076             if (ai != null) {
3077                 ResolveInfo ri = new ResolveInfo();
3078                 ri.activityInfo = ai;
3079                 list.add(ri);
3080             }
3081             return list;
3082         }
3083 
3084         // reader
3085         synchronized (mPackages) {
3086             String pkgName = intent.getPackage();
3087             if (pkgName == null) {
3088                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
3089             }
3090             final PackageParser.Package pkg = mPackages.get(pkgName);
3091             if (pkg != null) {
3092                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
3093                         userId);
3094             }
3095             return null;
3096         }
3097     }
3098 
3099     @Override
resolveService(Intent intent, String resolvedType, int flags, int userId)3100     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
3101         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
3102         if (!sUserManager.exists(userId)) return null;
3103         if (query != null) {
3104             if (query.size() >= 1) {
3105                 // If there is more than one service with the same priority,
3106                 // just arbitrarily pick the first one.
3107                 return query.get(0);
3108             }
3109         }
3110         return null;
3111     }
3112 
3113     @Override
queryIntentServices(Intent intent, String resolvedType, int flags, int userId)3114     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
3115             int userId) {
3116         if (!sUserManager.exists(userId)) return Collections.emptyList();
3117         ComponentName comp = intent.getComponent();
3118         if (comp == null) {
3119             if (intent.getSelector() != null) {
3120                 intent = intent.getSelector();
3121                 comp = intent.getComponent();
3122             }
3123         }
3124         if (comp != null) {
3125             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3126             final ServiceInfo si = getServiceInfo(comp, flags, userId);
3127             if (si != null) {
3128                 final ResolveInfo ri = new ResolveInfo();
3129                 ri.serviceInfo = si;
3130                 list.add(ri);
3131             }
3132             return list;
3133         }
3134 
3135         // reader
3136         synchronized (mPackages) {
3137             String pkgName = intent.getPackage();
3138             if (pkgName == null) {
3139                 return mServices.queryIntent(intent, resolvedType, flags, userId);
3140             }
3141             final PackageParser.Package pkg = mPackages.get(pkgName);
3142             if (pkg != null) {
3143                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3144                         userId);
3145             }
3146             return null;
3147         }
3148     }
3149 
3150     @Override
queryIntentContentProviders( Intent intent, String resolvedType, int flags, int userId)3151     public List<ResolveInfo> queryIntentContentProviders(
3152             Intent intent, String resolvedType, int flags, int userId) {
3153         if (!sUserManager.exists(userId)) return Collections.emptyList();
3154         ComponentName comp = intent.getComponent();
3155         if (comp == null) {
3156             if (intent.getSelector() != null) {
3157                 intent = intent.getSelector();
3158                 comp = intent.getComponent();
3159             }
3160         }
3161         if (comp != null) {
3162             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3163             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
3164             if (pi != null) {
3165                 final ResolveInfo ri = new ResolveInfo();
3166                 ri.providerInfo = pi;
3167                 list.add(ri);
3168             }
3169             return list;
3170         }
3171 
3172         // reader
3173         synchronized (mPackages) {
3174             String pkgName = intent.getPackage();
3175             if (pkgName == null) {
3176                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
3177             }
3178             final PackageParser.Package pkg = mPackages.get(pkgName);
3179             if (pkg != null) {
3180                 return mProviders.queryIntentForPackage(
3181                         intent, resolvedType, flags, pkg.providers, userId);
3182             }
3183             return null;
3184         }
3185     }
3186 
3187     @Override
getInstalledPackages(int flags, int userId)3188     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3189         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3190 
3191         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
3192 
3193         // writer
3194         synchronized (mPackages) {
3195             ArrayList<PackageInfo> list;
3196             if (listUninstalled) {
3197                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3198                 for (PackageSetting ps : mSettings.mPackages.values()) {
3199                     PackageInfo pi;
3200                     if (ps.pkg != null) {
3201                         pi = generatePackageInfo(ps.pkg, flags, userId);
3202                     } else {
3203                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3204                     }
3205                     if (pi != null) {
3206                         list.add(pi);
3207                     }
3208                 }
3209             } else {
3210                 list = new ArrayList<PackageInfo>(mPackages.size());
3211                 for (PackageParser.Package p : mPackages.values()) {
3212                     PackageInfo pi = generatePackageInfo(p, flags, userId);
3213                     if (pi != null) {
3214                         list.add(pi);
3215                     }
3216                 }
3217             }
3218 
3219             return new ParceledListSlice<PackageInfo>(list);
3220         }
3221     }
3222 
addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)3223     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3224             String[] permissions, boolean[] tmp, int flags, int userId) {
3225         int numMatch = 0;
3226         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3227         for (int i=0; i<permissions.length; i++) {
3228             if (gp.grantedPermissions.contains(permissions[i])) {
3229                 tmp[i] = true;
3230                 numMatch++;
3231             } else {
3232                 tmp[i] = false;
3233             }
3234         }
3235         if (numMatch == 0) {
3236             return;
3237         }
3238         PackageInfo pi;
3239         if (ps.pkg != null) {
3240             pi = generatePackageInfo(ps.pkg, flags, userId);
3241         } else {
3242             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3243         }
3244         if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3245             if (numMatch == permissions.length) {
3246                 pi.requestedPermissions = permissions;
3247             } else {
3248                 pi.requestedPermissions = new String[numMatch];
3249                 numMatch = 0;
3250                 for (int i=0; i<permissions.length; i++) {
3251                     if (tmp[i]) {
3252                         pi.requestedPermissions[numMatch] = permissions[i];
3253                         numMatch++;
3254                     }
3255                 }
3256             }
3257         }
3258         list.add(pi);
3259     }
3260 
3261     @Override
getPackagesHoldingPermissions( String[] permissions, int flags, int userId)3262     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3263             String[] permissions, int flags, int userId) {
3264         if (!sUserManager.exists(userId)) return null;
3265         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3266 
3267         // writer
3268         synchronized (mPackages) {
3269             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3270             boolean[] tmpBools = new boolean[permissions.length];
3271             if (listUninstalled) {
3272                 for (PackageSetting ps : mSettings.mPackages.values()) {
3273                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3274                 }
3275             } else {
3276                 for (PackageParser.Package pkg : mPackages.values()) {
3277                     PackageSetting ps = (PackageSetting)pkg.mExtras;
3278                     if (ps != null) {
3279                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3280                                 userId);
3281                     }
3282                 }
3283             }
3284 
3285             return new ParceledListSlice<PackageInfo>(list);
3286         }
3287     }
3288 
3289     @Override
getInstalledApplications(int flags, int userId)3290     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3291         if (!sUserManager.exists(userId)) return null;
3292         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3293 
3294         // writer
3295         synchronized (mPackages) {
3296             ArrayList<ApplicationInfo> list;
3297             if (listUninstalled) {
3298                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3299                 for (PackageSetting ps : mSettings.mPackages.values()) {
3300                     ApplicationInfo ai;
3301                     if (ps.pkg != null) {
3302                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3303                                 ps.readUserState(userId), userId);
3304                     } else {
3305                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3306                     }
3307                     if (ai != null) {
3308                         list.add(ai);
3309                     }
3310                 }
3311             } else {
3312                 list = new ArrayList<ApplicationInfo>(mPackages.size());
3313                 for (PackageParser.Package p : mPackages.values()) {
3314                     if (p.mExtras != null) {
3315                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3316                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3317                         if (ai != null) {
3318                             list.add(ai);
3319                         }
3320                     }
3321                 }
3322             }
3323 
3324             return new ParceledListSlice<ApplicationInfo>(list);
3325         }
3326     }
3327 
getPersistentApplications(int flags)3328     public List<ApplicationInfo> getPersistentApplications(int flags) {
3329         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3330 
3331         // reader
3332         synchronized (mPackages) {
3333             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3334             final int userId = UserHandle.getCallingUserId();
3335             while (i.hasNext()) {
3336                 final PackageParser.Package p = i.next();
3337                 if (p.applicationInfo != null
3338                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3339                         && (!mSafeMode || isSystemApp(p))) {
3340                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
3341                     if (ps != null) {
3342                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3343                                 ps.readUserState(userId), userId);
3344                         if (ai != null) {
3345                             finalList.add(ai);
3346                         }
3347                     }
3348                 }
3349             }
3350         }
3351 
3352         return finalList;
3353     }
3354 
3355     @Override
resolveContentProvider(String name, int flags, int userId)3356     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3357         if (!sUserManager.exists(userId)) return null;
3358         // reader
3359         synchronized (mPackages) {
3360             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
3361             PackageSetting ps = provider != null
3362                     ? mSettings.mPackages.get(provider.owner.packageName)
3363                     : null;
3364             return ps != null
3365                     && mSettings.isEnabledLPr(provider.info, flags, userId)
3366                     && (!mSafeMode || (provider.info.applicationInfo.flags
3367                             &ApplicationInfo.FLAG_SYSTEM) != 0)
3368                     ? PackageParser.generateProviderInfo(provider, flags,
3369                             ps.readUserState(userId), userId)
3370                     : null;
3371         }
3372     }
3373 
3374     /**
3375      * @deprecated
3376      */
3377     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)3378     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3379         // reader
3380         synchronized (mPackages) {
3381             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
3382                     .entrySet().iterator();
3383             final int userId = UserHandle.getCallingUserId();
3384             while (i.hasNext()) {
3385                 Map.Entry<String, PackageParser.Provider> entry = i.next();
3386                 PackageParser.Provider p = entry.getValue();
3387                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3388 
3389                 if (ps != null && p.syncable
3390                         && (!mSafeMode || (p.info.applicationInfo.flags
3391                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3392                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3393                             ps.readUserState(userId), userId);
3394                     if (info != null) {
3395                         outNames.add(entry.getKey());
3396                         outInfo.add(info);
3397                     }
3398                 }
3399             }
3400         }
3401     }
3402 
queryContentProviders(String processName, int uid, int flags)3403     public List<ProviderInfo> queryContentProviders(String processName,
3404             int uid, int flags) {
3405         ArrayList<ProviderInfo> finalList = null;
3406         // reader
3407         synchronized (mPackages) {
3408             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
3409             final int userId = processName != null ?
3410                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3411             while (i.hasNext()) {
3412                 final PackageParser.Provider p = i.next();
3413                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3414                 if (ps != null && p.info.authority != null
3415                         && (processName == null
3416                                 || (p.info.processName.equals(processName)
3417                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3418                         && mSettings.isEnabledLPr(p.info, flags, userId)
3419                         && (!mSafeMode
3420                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3421                     if (finalList == null) {
3422                         finalList = new ArrayList<ProviderInfo>(3);
3423                     }
3424                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3425                             ps.readUserState(userId), userId);
3426                     if (info != null) {
3427                         finalList.add(info);
3428                     }
3429                 }
3430             }
3431         }
3432 
3433         if (finalList != null) {
3434             Collections.sort(finalList, mProviderInitOrderSorter);
3435         }
3436 
3437         return finalList;
3438     }
3439 
getInstrumentationInfo(ComponentName name, int flags)3440     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
3441             int flags) {
3442         // reader
3443         synchronized (mPackages) {
3444             final PackageParser.Instrumentation i = mInstrumentation.get(name);
3445             return PackageParser.generateInstrumentationInfo(i, flags);
3446         }
3447     }
3448 
queryInstrumentation(String targetPackage, int flags)3449     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
3450             int flags) {
3451         ArrayList<InstrumentationInfo> finalList =
3452             new ArrayList<InstrumentationInfo>();
3453 
3454         // reader
3455         synchronized (mPackages) {
3456             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
3457             while (i.hasNext()) {
3458                 final PackageParser.Instrumentation p = i.next();
3459                 if (targetPackage == null
3460                         || targetPackage.equals(p.info.targetPackage)) {
3461                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
3462                             flags);
3463                     if (ii != null) {
3464                         finalList.add(ii);
3465                     }
3466                 }
3467             }
3468         }
3469 
3470         return finalList;
3471     }
3472 
scanDirLI(File dir, int flags, int scanMode, long currentTime)3473     private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
3474         String[] files = dir.list();
3475         if (files == null) {
3476             Log.d(TAG, "No files in app dir " + dir);
3477             return;
3478         }
3479 
3480         if (DEBUG_PACKAGE_SCANNING) {
3481             Log.d(TAG, "Scanning app dir " + dir + " scanMode=" + scanMode
3482                     + " flags=0x" + Integer.toHexString(flags));
3483         }
3484 
3485         int i;
3486         for (i=0; i<files.length; i++) {
3487             File file = new File(dir, files[i]);
3488             if (!isPackageFilename(files[i])) {
3489                 // Ignore entries which are not apk's
3490                 continue;
3491             }
3492             PackageParser.Package pkg = scanPackageLI(file,
3493                     flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
3494             // Don't mess around with apps in system partition.
3495             if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
3496                     mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
3497                 // Delete the apk
3498                 Slog.w(TAG, "Cleaning up failed install of " + file);
3499                 file.delete();
3500             }
3501         }
3502     }
3503 
getSettingsProblemFile()3504     private static File getSettingsProblemFile() {
3505         File dataDir = Environment.getDataDirectory();
3506         File systemDir = new File(dataDir, "system");
3507         File fname = new File(systemDir, "uiderrors.txt");
3508         return fname;
3509     }
3510 
reportSettingsProblem(int priority, String msg)3511     static void reportSettingsProblem(int priority, String msg) {
3512         try {
3513             File fname = getSettingsProblemFile();
3514             FileOutputStream out = new FileOutputStream(fname, true);
3515             PrintWriter pw = new FastPrintWriter(out);
3516             SimpleDateFormat formatter = new SimpleDateFormat();
3517             String dateString = formatter.format(new Date(System.currentTimeMillis()));
3518             pw.println(dateString + ": " + msg);
3519             pw.close();
3520             FileUtils.setPermissions(
3521                     fname.toString(),
3522                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
3523                     -1, -1);
3524         } catch (java.io.IOException e) {
3525         }
3526         Slog.println(priority, TAG, msg);
3527     }
3528 
collectCertificatesLI(PackageParser pp, PackageSetting ps, PackageParser.Package pkg, File srcFile, int parseFlags)3529     private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
3530             PackageParser.Package pkg, File srcFile, int parseFlags) {
3531         if (GET_CERTIFICATES) {
3532             if (ps != null
3533                     && ps.codePath.equals(srcFile)
3534                     && ps.timeStamp == srcFile.lastModified()) {
3535                 if (ps.signatures.mSignatures != null
3536                         && ps.signatures.mSignatures.length != 0) {
3537                     // Optimization: reuse the existing cached certificates
3538                     // if the package appears to be unchanged.
3539                     pkg.mSignatures = ps.signatures.mSignatures;
3540                     return true;
3541                 }
3542 
3543                 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
3544             } else {
3545                 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
3546             }
3547 
3548             if (!pp.collectCertificates(pkg, parseFlags)) {
3549                 mLastScanError = pp.getParseError();
3550                 return false;
3551             }
3552         }
3553         return true;
3554     }
3555 
3556     /*
3557      *  Scan a package and return the newly parsed package.
3558      *  Returns null in case of errors and the error code is stored in mLastScanError
3559      */
scanPackageLI(File scanFile, int parseFlags, int scanMode, long currentTime, UserHandle user)3560     private PackageParser.Package scanPackageLI(File scanFile,
3561             int parseFlags, int scanMode, long currentTime, UserHandle user) {
3562         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
3563         String scanPath = scanFile.getPath();
3564         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath);
3565         parseFlags |= mDefParseFlags;
3566         PackageParser pp = new PackageParser(scanPath);
3567         pp.setSeparateProcesses(mSeparateProcesses);
3568         pp.setOnlyCoreApps(mOnlyCore);
3569         final PackageParser.Package pkg = pp.parsePackage(scanFile,
3570                 scanPath, mMetrics, parseFlags);
3571 
3572         if (pkg == null) {
3573             mLastScanError = pp.getParseError();
3574             return null;
3575         }
3576 
3577         PackageSetting ps = null;
3578         PackageSetting updatedPkg;
3579         // reader
3580         synchronized (mPackages) {
3581             // Look to see if we already know about this package.
3582             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
3583             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
3584                 // This package has been renamed to its original name.  Let's
3585                 // use that.
3586                 ps = mSettings.peekPackageLPr(oldName);
3587             }
3588             // If there was no original package, see one for the real package name.
3589             if (ps == null) {
3590                 ps = mSettings.peekPackageLPr(pkg.packageName);
3591             }
3592             // Check to see if this package could be hiding/updating a system
3593             // package.  Must look for it either under the original or real
3594             // package name depending on our state.
3595             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
3596             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
3597         }
3598         // First check if this is a system package that may involve an update
3599         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
3600             if (ps != null && !ps.codePath.equals(scanFile)) {
3601                 // The path has changed from what was last scanned...  check the
3602                 // version of the new path against what we have stored to determine
3603                 // what to do.
3604                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
3605                 if (pkg.mVersionCode < ps.versionCode) {
3606                     // The system package has been updated and the code path does not match
3607                     // Ignore entry. Skip it.
3608                     Log.i(TAG, "Package " + ps.name + " at " + scanFile
3609                             + " ignored: updated version " + ps.versionCode
3610                             + " better than this " + pkg.mVersionCode);
3611                     if (!updatedPkg.codePath.equals(scanFile)) {
3612                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
3613                                 + ps.name + " changing from " + updatedPkg.codePathString
3614                                 + " to " + scanFile);
3615                         updatedPkg.codePath = scanFile;
3616                         updatedPkg.codePathString = scanFile.toString();
3617                         // This is the point at which we know that the system-disk APK
3618                         // for this package has moved during a reboot (e.g. due to an OTA),
3619                         // so we need to reevaluate it for privilege policy.
3620                         if (locationIsPrivileged(scanFile)) {
3621                             updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
3622                         }
3623                     }
3624                     updatedPkg.pkg = pkg;
3625                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3626                     return null;
3627                 } else {
3628                     // The current app on the system partion is better than
3629                     // what we have updated to on the data partition; switch
3630                     // back to the system partition version.
3631                     // At this point, its safely assumed that package installation for
3632                     // apps in system partition will go through. If not there won't be a working
3633                     // version of the app
3634                     // writer
3635                     synchronized (mPackages) {
3636                         // Just remove the loaded entries from package lists.
3637                         mPackages.remove(ps.name);
3638                     }
3639                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile
3640                             + "reverting from " + ps.codePathString
3641                             + ": new version " + pkg.mVersionCode
3642                             + " better than installed " + ps.versionCode);
3643 
3644                     InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3645                             ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3646                     synchronized (mInstallLock) {
3647                         args.cleanUpResourcesLI();
3648                     }
3649                     synchronized (mPackages) {
3650                         mSettings.enableSystemPackageLPw(ps.name);
3651                     }
3652                 }
3653             }
3654         }
3655 
3656         if (updatedPkg != null) {
3657             // An updated system app will not have the PARSE_IS_SYSTEM flag set
3658             // initially
3659             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
3660 
3661             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
3662             // flag set initially
3663             if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
3664                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
3665             }
3666         }
3667         // Verify certificates against what was last scanned
3668         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
3669             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
3670             return null;
3671         }
3672 
3673         /*
3674          * A new system app appeared, but we already had a non-system one of the
3675          * same name installed earlier.
3676          */
3677         boolean shouldHideSystemApp = false;
3678         if (updatedPkg == null && ps != null
3679                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
3680             /*
3681              * Check to make sure the signatures match first. If they don't,
3682              * wipe the installed application and its data.
3683              */
3684             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
3685                     != PackageManager.SIGNATURE_MATCH) {
3686                 if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!");
3687                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
3688                 ps = null;
3689             } else {
3690                 /*
3691                  * If the newly-added system app is an older version than the
3692                  * already installed version, hide it. It will be scanned later
3693                  * and re-added like an update.
3694                  */
3695                 if (pkg.mVersionCode < ps.versionCode) {
3696                     shouldHideSystemApp = true;
3697                 } else {
3698                     /*
3699                      * The newly found system app is a newer version that the
3700                      * one previously installed. Simply remove the
3701                      * already-installed application and replace it with our own
3702                      * while keeping the application data.
3703                      */
3704                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
3705                             + ps.codePathString + ": new version " + pkg.mVersionCode
3706                             + " better than installed " + ps.versionCode);
3707                     InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3708                             ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3709                     synchronized (mInstallLock) {
3710                         args.cleanUpResourcesLI();
3711                     }
3712                 }
3713             }
3714         }
3715 
3716         // The apk is forward locked (not public) if its code and resources
3717         // are kept in different files. (except for app in either system or
3718         // vendor path).
3719         // TODO grab this value from PackageSettings
3720         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
3721             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
3722                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
3723             }
3724         }
3725 
3726         String codePath = null;
3727         String resPath = null;
3728         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
3729             if (ps != null && ps.resourcePathString != null) {
3730                 resPath = ps.resourcePathString;
3731             } else {
3732                 // Should not happen at all. Just log an error.
3733                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
3734             }
3735         } else {
3736             resPath = pkg.mScanPath;
3737         }
3738 
3739         codePath = pkg.mScanPath;
3740         // Set application objects path explicitly.
3741         setApplicationInfoPaths(pkg, codePath, resPath);
3742         // Note that we invoke the following method only if we are about to unpack an application
3743         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
3744                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
3745 
3746         /*
3747          * If the system app should be overridden by a previously installed
3748          * data, hide the system app now and let the /data/app scan pick it up
3749          * again.
3750          */
3751         if (shouldHideSystemApp) {
3752             synchronized (mPackages) {
3753                 /*
3754                  * We have to grant systems permissions before we hide, because
3755                  * grantPermissions will assume the package update is trying to
3756                  * expand its permissions.
3757                  */
3758                 grantPermissionsLPw(pkg, true);
3759                 mSettings.disableSystemPackageLPw(pkg.packageName);
3760             }
3761         }
3762 
3763         return scannedPkg;
3764     }
3765 
setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath, String destResPath)3766     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
3767             String destResPath) {
3768         pkg.mPath = pkg.mScanPath = destCodePath;
3769         pkg.applicationInfo.sourceDir = destCodePath;
3770         pkg.applicationInfo.publicSourceDir = destResPath;
3771     }
3772 
fixProcessName(String defProcessName, String processName, int uid)3773     private static String fixProcessName(String defProcessName,
3774             String processName, int uid) {
3775         if (processName == null) {
3776             return defProcessName;
3777         }
3778         return processName;
3779     }
3780 
verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)3781     private boolean verifySignaturesLP(PackageSetting pkgSetting,
3782             PackageParser.Package pkg) {
3783         if (pkgSetting.signatures.mSignatures != null) {
3784             // Already existing package. Make sure signatures match
3785             if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
3786                 PackageManager.SIGNATURE_MATCH) {
3787                     Slog.e(TAG, "Package " + pkg.packageName
3788                             + " signatures do not match the previously installed version; ignoring!");
3789                     mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3790                     return false;
3791                 }
3792         }
3793         // Check for shared user signatures
3794         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
3795             if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
3796                     pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
3797                 Slog.e(TAG, "Package " + pkg.packageName
3798                         + " has no signatures that match those in shared user "
3799                         + pkgSetting.sharedUser.name + "; ignoring!");
3800                 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3801                 return false;
3802             }
3803         }
3804         return true;
3805     }
3806 
3807     /**
3808      * Enforces that only the system UID or root's UID can call a method exposed
3809      * via Binder.
3810      *
3811      * @param message used as message if SecurityException is thrown
3812      * @throws SecurityException if the caller is not system or root
3813      */
enforceSystemOrRoot(String message)3814     private static final void enforceSystemOrRoot(String message) {
3815         final int uid = Binder.getCallingUid();
3816         if (uid != Process.SYSTEM_UID && uid != 0) {
3817             throw new SecurityException(message);
3818         }
3819     }
3820 
performBootDexOpt()3821     public void performBootDexOpt() {
3822         HashSet<PackageParser.Package> pkgs = null;
3823         synchronized (mPackages) {
3824             pkgs = mDeferredDexOpt;
3825             mDeferredDexOpt = null;
3826         }
3827         if (pkgs != null) {
3828             int i = 0;
3829             for (PackageParser.Package pkg : pkgs) {
3830                 if (!isFirstBoot()) {
3831                     i++;
3832                     try {
3833                         ActivityManagerNative.getDefault().showBootMessage(
3834                                 mContext.getResources().getString(
3835                                         com.android.internal.R.string.android_upgrading_apk,
3836                                         i, pkgs.size()), true);
3837                     } catch (RemoteException e) {
3838                     }
3839                 }
3840                 PackageParser.Package p = pkg;
3841                 synchronized (mInstallLock) {
3842                     if (!p.mDidDexOpt) {
3843                         performDexOptLI(p, false, false, true);
3844                     }
3845                 }
3846             }
3847         }
3848     }
3849 
performDexOpt(String packageName)3850     public boolean performDexOpt(String packageName) {
3851         enforceSystemOrRoot("Only the system can request dexopt be performed");
3852 
3853         if (!mNoDexOpt) {
3854             return false;
3855         }
3856 
3857         PackageParser.Package p;
3858         synchronized (mPackages) {
3859             p = mPackages.get(packageName);
3860             if (p == null || p.mDidDexOpt) {
3861                 return false;
3862             }
3863         }
3864         synchronized (mInstallLock) {
3865             return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED;
3866         }
3867     }
3868 
performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer, HashSet<String> done)3869     private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer,
3870             HashSet<String> done) {
3871         for (int i=0; i<libs.size(); i++) {
3872             PackageParser.Package libPkg;
3873             String libName;
3874             synchronized (mPackages) {
3875                 libName = libs.get(i);
3876                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
3877                 if (lib != null && lib.apk != null) {
3878                     libPkg = mPackages.get(lib.apk);
3879                 } else {
3880                     libPkg = null;
3881                 }
3882             }
3883             if (libPkg != null && !done.contains(libName)) {
3884                 performDexOptLI(libPkg, forceDex, defer, done);
3885             }
3886         }
3887     }
3888 
3889     static final int DEX_OPT_SKIPPED = 0;
3890     static final int DEX_OPT_PERFORMED = 1;
3891     static final int DEX_OPT_DEFERRED = 2;
3892     static final int DEX_OPT_FAILED = -1;
3893 
performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer, HashSet<String> done)3894     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
3895             HashSet<String> done) {
3896         boolean performed = false;
3897         if (done != null) {
3898             done.add(pkg.packageName);
3899             if (pkg.usesLibraries != null) {
3900                 performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done);
3901             }
3902             if (pkg.usesOptionalLibraries != null) {
3903                 performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done);
3904             }
3905         }
3906         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
3907             String path = pkg.mScanPath;
3908             int ret = 0;
3909             try {
3910                 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
3911                     if (!forceDex && defer) {
3912                         if (mDeferredDexOpt == null) {
3913                             mDeferredDexOpt = new HashSet<PackageParser.Package>();
3914                         }
3915                         mDeferredDexOpt.add(pkg);
3916                         return DEX_OPT_DEFERRED;
3917                     } else {
3918                         Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
3919                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
3920                         ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg));
3921                         pkg.mDidDexOpt = true;
3922                         performed = true;
3923                     }
3924                 }
3925             } catch (FileNotFoundException e) {
3926                 Slog.w(TAG, "Apk not found for dexopt: " + path);
3927                 ret = -1;
3928             } catch (IOException e) {
3929                 Slog.w(TAG, "IOException reading apk: " + path, e);
3930                 ret = -1;
3931             } catch (dalvik.system.StaleDexCacheError e) {
3932                 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
3933                 ret = -1;
3934             } catch (Exception e) {
3935                 Slog.w(TAG, "Exception when doing dexopt : ", e);
3936                 ret = -1;
3937             }
3938             if (ret < 0) {
3939                 //error from installer
3940                 return DEX_OPT_FAILED;
3941             }
3942         }
3943 
3944         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
3945     }
3946 
performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer, boolean inclDependencies)3947     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
3948             boolean inclDependencies) {
3949         HashSet<String> done;
3950         boolean performed = false;
3951         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
3952             done = new HashSet<String>();
3953             done.add(pkg.packageName);
3954         } else {
3955             done = null;
3956         }
3957         return performDexOptLI(pkg, forceDex, defer, done);
3958     }
3959 
verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)3960     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
3961         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3962             Slog.w(TAG, "Unable to update from " + oldPkg.name
3963                     + " to " + newPkg.packageName
3964                     + ": old package not in system partition");
3965             return false;
3966         } else if (mPackages.get(oldPkg.name) != null) {
3967             Slog.w(TAG, "Unable to update from " + oldPkg.name
3968                     + " to " + newPkg.packageName
3969                     + ": old package still exists");
3970             return false;
3971         }
3972         return true;
3973     }
3974 
getDataPathForUser(int userId)3975     File getDataPathForUser(int userId) {
3976         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
3977     }
3978 
getDataPathForPackage(String packageName, int userId)3979     private File getDataPathForPackage(String packageName, int userId) {
3980         /*
3981          * Until we fully support multiple users, return the directory we
3982          * previously would have. The PackageManagerTests will need to be
3983          * revised when this is changed back..
3984          */
3985         if (userId == 0) {
3986             return new File(mAppDataDir, packageName);
3987         } else {
3988             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
3989                 + File.separator + packageName);
3990         }
3991     }
3992 
createDataDirsLI(String packageName, int uid, String seinfo)3993     private int createDataDirsLI(String packageName, int uid, String seinfo) {
3994         int[] users = sUserManager.getUserIds();
3995         int res = mInstaller.install(packageName, uid, uid, seinfo);
3996         if (res < 0) {
3997             return res;
3998         }
3999         for (int user : users) {
4000             if (user != 0) {
4001                 res = mInstaller.createUserData(packageName,
4002                         UserHandle.getUid(user, uid), user);
4003                 if (res < 0) {
4004                     return res;
4005                 }
4006             }
4007         }
4008         return res;
4009     }
4010 
removeDataDirsLI(String packageName)4011     private int removeDataDirsLI(String packageName) {
4012         int[] users = sUserManager.getUserIds();
4013         int res = 0;
4014         for (int user : users) {
4015             int resInner = mInstaller.remove(packageName, user);
4016             if (resInner < 0) {
4017                 res = resInner;
4018             }
4019         }
4020 
4021         final File nativeLibraryFile = new File(mAppLibInstallDir, packageName);
4022         NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
4023         if (!nativeLibraryFile.delete()) {
4024             Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath());
4025         }
4026 
4027         return res;
4028     }
4029 
addSharedLibraryLPw(final SharedLibraryEntry file, int num, PackageParser.Package changingLib)4030     private int addSharedLibraryLPw(final SharedLibraryEntry file, int num,
4031             PackageParser.Package changingLib) {
4032         if (file.path != null) {
4033             mTmpSharedLibraries[num] = file.path;
4034             return num+1;
4035         }
4036         PackageParser.Package p = mPackages.get(file.apk);
4037         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
4038             // If we are doing this while in the middle of updating a library apk,
4039             // then we need to make sure to use that new apk for determining the
4040             // dependencies here.  (We haven't yet finished committing the new apk
4041             // to the package manager state.)
4042             if (p == null || p.packageName.equals(changingLib.packageName)) {
4043                 p = changingLib;
4044             }
4045         }
4046         if (p != null) {
4047             String path = p.mPath;
4048             for (int i=0; i<num; i++) {
4049                 if (mTmpSharedLibraries[i].equals(path)) {
4050                     return num;
4051                 }
4052             }
4053             mTmpSharedLibraries[num] = p.mPath;
4054             return num+1;
4055         }
4056         return num;
4057     }
4058 
updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)4059     private boolean updateSharedLibrariesLPw(PackageParser.Package pkg,
4060             PackageParser.Package changingLib) {
4061         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
4062             if (mTmpSharedLibraries == null ||
4063                     mTmpSharedLibraries.length < mSharedLibraries.size()) {
4064                 mTmpSharedLibraries = new String[mSharedLibraries.size()];
4065             }
4066             int num = 0;
4067             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
4068             for (int i=0; i<N; i++) {
4069                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
4070                 if (file == null) {
4071                     Slog.e(TAG, "Package " + pkg.packageName
4072                             + " requires unavailable shared library "
4073                             + pkg.usesLibraries.get(i) + "; failing!");
4074                     mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
4075                     return false;
4076                 }
4077                 num = addSharedLibraryLPw(file, num, changingLib);
4078             }
4079             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
4080             for (int i=0; i<N; i++) {
4081                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
4082                 if (file == null) {
4083                     Slog.w(TAG, "Package " + pkg.packageName
4084                             + " desires unavailable shared library "
4085                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
4086                 } else {
4087                     num = addSharedLibraryLPw(file, num, changingLib);
4088                 }
4089             }
4090             if (num > 0) {
4091                 pkg.usesLibraryFiles = new String[num];
4092                 System.arraycopy(mTmpSharedLibraries, 0,
4093                         pkg.usesLibraryFiles, 0, num);
4094             } else {
4095                 pkg.usesLibraryFiles = null;
4096             }
4097         }
4098         return true;
4099     }
4100 
hasString(List<String> list, List<String> which)4101     private static boolean hasString(List<String> list, List<String> which) {
4102         if (list == null) {
4103             return false;
4104         }
4105         for (int i=list.size()-1; i>=0; i--) {
4106             for (int j=which.size()-1; j>=0; j--) {
4107                 if (which.get(j).equals(list.get(i))) {
4108                     return true;
4109                 }
4110             }
4111         }
4112         return false;
4113     }
4114 
updateAllSharedLibrariesLPw()4115     private void updateAllSharedLibrariesLPw() {
4116         for (PackageParser.Package pkg : mPackages.values()) {
4117             updateSharedLibrariesLPw(pkg, null);
4118         }
4119     }
4120 
updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)4121     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
4122             PackageParser.Package changingPkg) {
4123         ArrayList<PackageParser.Package> res = null;
4124         for (PackageParser.Package pkg : mPackages.values()) {
4125             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
4126                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
4127                 if (res == null) {
4128                     res = new ArrayList<PackageParser.Package>();
4129                 }
4130                 res.add(pkg);
4131                 updateSharedLibrariesLPw(pkg, changingPkg);
4132             }
4133         }
4134         return res;
4135     }
4136 
scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, long currentTime, UserHandle user)4137     private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
4138             int parseFlags, int scanMode, long currentTime, UserHandle user) {
4139         File scanFile = new File(pkg.mScanPath);
4140         if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
4141                 pkg.applicationInfo.publicSourceDir == null) {
4142             // Bail out. The resource and code paths haven't been set.
4143             Slog.w(TAG, " Code and resource paths haven't been set correctly");
4144             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4145             return null;
4146         }
4147 
4148         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4149             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
4150         }
4151 
4152         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
4153             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
4154         }
4155 
4156         if (mCustomResolverComponentName != null &&
4157                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
4158             setUpCustomResolverActivity(pkg);
4159         }
4160 
4161         if (pkg.packageName.equals("android")) {
4162             synchronized (mPackages) {
4163                 if (mAndroidApplication != null) {
4164                     Slog.w(TAG, "*************************************************");
4165                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
4166                     Slog.w(TAG, " file=" + scanFile);
4167                     Slog.w(TAG, "*************************************************");
4168                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4169                     return null;
4170                 }
4171 
4172                 // Set up information for our fall-back user intent resolution activity.
4173                 mPlatformPackage = pkg;
4174                 pkg.mVersionCode = mSdkVersion;
4175                 mAndroidApplication = pkg.applicationInfo;
4176 
4177                 if (!mResolverReplaced) {
4178                     mResolveActivity.applicationInfo = mAndroidApplication;
4179                     mResolveActivity.name = ResolverActivity.class.getName();
4180                     mResolveActivity.packageName = mAndroidApplication.packageName;
4181                     mResolveActivity.processName = "system:ui";
4182                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
4183                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
4184                     mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
4185                     mResolveActivity.exported = true;
4186                     mResolveActivity.enabled = true;
4187                     mResolveInfo.activityInfo = mResolveActivity;
4188                     mResolveInfo.priority = 0;
4189                     mResolveInfo.preferredOrder = 0;
4190                     mResolveInfo.match = 0;
4191                     mResolveComponentName = new ComponentName(
4192                             mAndroidApplication.packageName, mResolveActivity.name);
4193                 }
4194             }
4195         }
4196 
4197         if (DEBUG_PACKAGE_SCANNING) {
4198             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4199                 Log.d(TAG, "Scanning package " + pkg.packageName);
4200         }
4201 
4202         if (mPackages.containsKey(pkg.packageName)
4203                 || mSharedLibraries.containsKey(pkg.packageName)) {
4204             Slog.w(TAG, "Application package " + pkg.packageName
4205                     + " already installed.  Skipping duplicate.");
4206             mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4207             return null;
4208         }
4209 
4210         // Initialize package source and resource directories
4211         File destCodeFile = new File(pkg.applicationInfo.sourceDir);
4212         File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
4213 
4214         SharedUserSetting suid = null;
4215         PackageSetting pkgSetting = null;
4216 
4217         if (!isSystemApp(pkg)) {
4218             // Only system apps can use these features.
4219             pkg.mOriginalPackages = null;
4220             pkg.mRealPackage = null;
4221             pkg.mAdoptPermissions = null;
4222         }
4223 
4224         // writer
4225         synchronized (mPackages) {
4226             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4227                 // Check all shared libraries and map to their actual file path.
4228                 // We only do this here for apps not on a system dir, because those
4229                 // are the only ones that can fail an install due to this.  We
4230                 // will take care of the system apps by updating all of their
4231                 // library paths after the scan is done.
4232                 if (!updateSharedLibrariesLPw(pkg, null)) {
4233                     return null;
4234                 }
4235             }
4236 
4237             if (pkg.mSharedUserId != null) {
4238                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
4239                 if (suid == null) {
4240                     Slog.w(TAG, "Creating application package " + pkg.packageName
4241                             + " for shared user failed");
4242                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4243                     return null;
4244                 }
4245                 if (DEBUG_PACKAGE_SCANNING) {
4246                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4247                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
4248                                 + "): packages=" + suid.packages);
4249                 }
4250             }
4251 
4252             // Check if we are renaming from an original package name.
4253             PackageSetting origPackage = null;
4254             String realName = null;
4255             if (pkg.mOriginalPackages != null) {
4256                 // This package may need to be renamed to a previously
4257                 // installed name.  Let's check on that...
4258                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
4259                 if (pkg.mOriginalPackages.contains(renamed)) {
4260                     // This package had originally been installed as the
4261                     // original name, and we have already taken care of
4262                     // transitioning to the new one.  Just update the new
4263                     // one to continue using the old name.
4264                     realName = pkg.mRealPackage;
4265                     if (!pkg.packageName.equals(renamed)) {
4266                         // Callers into this function may have already taken
4267                         // care of renaming the package; only do it here if
4268                         // it is not already done.
4269                         pkg.setPackageName(renamed);
4270                     }
4271 
4272                 } else {
4273                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
4274                         if ((origPackage = mSettings.peekPackageLPr(
4275                                 pkg.mOriginalPackages.get(i))) != null) {
4276                             // We do have the package already installed under its
4277                             // original name...  should we use it?
4278                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
4279                                 // New package is not compatible with original.
4280                                 origPackage = null;
4281                                 continue;
4282                             } else if (origPackage.sharedUser != null) {
4283                                 // Make sure uid is compatible between packages.
4284                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
4285                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
4286                                             + " to " + pkg.packageName + ": old uid "
4287                                             + origPackage.sharedUser.name
4288                                             + " differs from " + pkg.mSharedUserId);
4289                                     origPackage = null;
4290                                     continue;
4291                                 }
4292                             } else {
4293                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
4294                                         + pkg.packageName + " to old name " + origPackage.name);
4295                             }
4296                             break;
4297                         }
4298                     }
4299                 }
4300             }
4301 
4302             if (mTransferedPackages.contains(pkg.packageName)) {
4303                 Slog.w(TAG, "Package " + pkg.packageName
4304                         + " was transferred to another, but its .apk remains");
4305             }
4306 
4307             // Just create the setting, don't add it yet. For already existing packages
4308             // the PkgSetting exists already and doesn't have to be created.
4309             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
4310                     destResourceFile, pkg.applicationInfo.nativeLibraryDir,
4311                     pkg.applicationInfo.flags, user, false);
4312             if (pkgSetting == null) {
4313                 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
4314                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4315                 return null;
4316             }
4317 
4318             if (pkgSetting.origPackage != null) {
4319                 // If we are first transitioning from an original package,
4320                 // fix up the new package's name now.  We need to do this after
4321                 // looking up the package under its new name, so getPackageLP
4322                 // can take care of fiddling things correctly.
4323                 pkg.setPackageName(origPackage.name);
4324 
4325                 // File a report about this.
4326                 String msg = "New package " + pkgSetting.realName
4327                         + " renamed to replace old package " + pkgSetting.name;
4328                 reportSettingsProblem(Log.WARN, msg);
4329 
4330                 // Make a note of it.
4331                 mTransferedPackages.add(origPackage.name);
4332 
4333                 // No longer need to retain this.
4334                 pkgSetting.origPackage = null;
4335             }
4336 
4337             if (realName != null) {
4338                 // Make a note of it.
4339                 mTransferedPackages.add(pkg.packageName);
4340             }
4341 
4342             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
4343                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
4344             }
4345 
4346             if (mFoundPolicyFile) {
4347                 SELinuxMMAC.assignSeinfoValue(pkg);
4348             }
4349 
4350             pkg.applicationInfo.uid = pkgSetting.appId;
4351             pkg.mExtras = pkgSetting;
4352 
4353             if (!verifySignaturesLP(pkgSetting, pkg)) {
4354                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4355                     return null;
4356                 }
4357                 // The signature has changed, but this package is in the system
4358                 // image...  let's recover!
4359                 pkgSetting.signatures.mSignatures = pkg.mSignatures;
4360                 // However...  if this package is part of a shared user, but it
4361                 // doesn't match the signature of the shared user, let's fail.
4362                 // What this means is that you can't change the signatures
4363                 // associated with an overall shared user, which doesn't seem all
4364                 // that unreasonable.
4365                 if (pkgSetting.sharedUser != null) {
4366                     if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4367                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
4368                         Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
4369                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
4370                         return null;
4371                     }
4372                 }
4373                 // File a report about this.
4374                 String msg = "System package " + pkg.packageName
4375                         + " signature changed; retaining data.";
4376                 reportSettingsProblem(Log.WARN, msg);
4377             }
4378 
4379             // Verify that this new package doesn't have any content providers
4380             // that conflict with existing packages.  Only do this if the
4381             // package isn't already installed, since we don't want to break
4382             // things that are installed.
4383             if ((scanMode&SCAN_NEW_INSTALL) != 0) {
4384                 final int N = pkg.providers.size();
4385                 int i;
4386                 for (i=0; i<N; i++) {
4387                     PackageParser.Provider p = pkg.providers.get(i);
4388                     if (p.info.authority != null) {
4389                         String names[] = p.info.authority.split(";");
4390                         for (int j = 0; j < names.length; j++) {
4391                             if (mProvidersByAuthority.containsKey(names[j])) {
4392                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
4393                                 Slog.w(TAG, "Can't install because provider name " + names[j] +
4394                                         " (in package " + pkg.applicationInfo.packageName +
4395                                         ") is already used by "
4396                                         + ((other != null && other.getComponentName() != null)
4397                                                 ? other.getComponentName().getPackageName() : "?"));
4398                                 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
4399                                 return null;
4400                             }
4401                         }
4402                     }
4403                 }
4404             }
4405 
4406             if (pkg.mAdoptPermissions != null) {
4407                 // This package wants to adopt ownership of permissions from
4408                 // another package.
4409                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
4410                     final String origName = pkg.mAdoptPermissions.get(i);
4411                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
4412                     if (orig != null) {
4413                         if (verifyPackageUpdateLPr(orig, pkg)) {
4414                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
4415                                     + pkg.packageName);
4416                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
4417                         }
4418                     }
4419                 }
4420             }
4421         }
4422 
4423         final String pkgName = pkg.packageName;
4424 
4425         final long scanFileTime = scanFile.lastModified();
4426         final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
4427         pkg.applicationInfo.processName = fixProcessName(
4428                 pkg.applicationInfo.packageName,
4429                 pkg.applicationInfo.processName,
4430                 pkg.applicationInfo.uid);
4431 
4432         File dataPath;
4433         if (mPlatformPackage == pkg) {
4434             // The system package is special.
4435             dataPath = new File (Environment.getDataDirectory(), "system");
4436             pkg.applicationInfo.dataDir = dataPath.getPath();
4437         } else {
4438             // This is a normal package, need to make its data directory.
4439             dataPath = getDataPathForPackage(pkg.packageName, 0);
4440 
4441             boolean uidError = false;
4442 
4443             if (dataPath.exists()) {
4444                 int currentUid = 0;
4445                 try {
4446                     StructStat stat = Libcore.os.stat(dataPath.getPath());
4447                     currentUid = stat.st_uid;
4448                 } catch (ErrnoException e) {
4449                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
4450                 }
4451 
4452                 // If we have mismatched owners for the data path, we have a problem.
4453                 if (currentUid != pkg.applicationInfo.uid) {
4454                     boolean recovered = false;
4455                     if (currentUid == 0) {
4456                         // The directory somehow became owned by root.  Wow.
4457                         // This is probably because the system was stopped while
4458                         // installd was in the middle of messing with its libs
4459                         // directory.  Ask installd to fix that.
4460                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
4461                                 pkg.applicationInfo.uid);
4462                         if (ret >= 0) {
4463                             recovered = true;
4464                             String msg = "Package " + pkg.packageName
4465                                     + " unexpectedly changed to uid 0; recovered to " +
4466                                     + pkg.applicationInfo.uid;
4467                             reportSettingsProblem(Log.WARN, msg);
4468                         }
4469                     }
4470                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4471                             || (scanMode&SCAN_BOOTING) != 0)) {
4472                         // If this is a system app, we can at least delete its
4473                         // current data so the application will still work.
4474                         int ret = removeDataDirsLI(pkgName);
4475                         if (ret >= 0) {
4476                             // TODO: Kill the processes first
4477                             // Old data gone!
4478                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4479                                     ? "System package " : "Third party package ";
4480                             String msg = prefix + pkg.packageName
4481                                     + " has changed from uid: "
4482                                     + currentUid + " to "
4483                                     + pkg.applicationInfo.uid + "; old data erased";
4484                             reportSettingsProblem(Log.WARN, msg);
4485                             recovered = true;
4486 
4487                             // And now re-install the app.
4488                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4489                                                    pkg.applicationInfo.seinfo);
4490                             if (ret == -1) {
4491                                 // Ack should not happen!
4492                                 msg = prefix + pkg.packageName
4493                                         + " could not have data directory re-created after delete.";
4494                                 reportSettingsProblem(Log.WARN, msg);
4495                                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4496                                 return null;
4497                             }
4498                         }
4499                         if (!recovered) {
4500                             mHasSystemUidErrors = true;
4501                         }
4502                     } else if (!recovered) {
4503                         // If we allow this install to proceed, we will be broken.
4504                         // Abort, abort!
4505                         mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
4506                         return null;
4507                     }
4508                     if (!recovered) {
4509                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
4510                             + pkg.applicationInfo.uid + "/fs_"
4511                             + currentUid;
4512                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
4513                         String msg = "Package " + pkg.packageName
4514                                 + " has mismatched uid: "
4515                                 + currentUid + " on disk, "
4516                                 + pkg.applicationInfo.uid + " in settings";
4517                         // writer
4518                         synchronized (mPackages) {
4519                             mSettings.mReadMessages.append(msg);
4520                             mSettings.mReadMessages.append('\n');
4521                             uidError = true;
4522                             if (!pkgSetting.uidError) {
4523                                 reportSettingsProblem(Log.ERROR, msg);
4524                             }
4525                         }
4526                     }
4527                 }
4528                 pkg.applicationInfo.dataDir = dataPath.getPath();
4529             } else {
4530                 if (DEBUG_PACKAGE_SCANNING) {
4531                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4532                         Log.v(TAG, "Want this data dir: " + dataPath);
4533                 }
4534                 //invoke installer to do the actual installation
4535                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4536                                            pkg.applicationInfo.seinfo);
4537                 if (ret < 0) {
4538                     // Error from installer
4539                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4540                     return null;
4541                 }
4542 
4543                 if (dataPath.exists()) {
4544                     pkg.applicationInfo.dataDir = dataPath.getPath();
4545                 } else {
4546                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
4547                     pkg.applicationInfo.dataDir = null;
4548                 }
4549             }
4550 
4551             /*
4552              * Set the data dir to the default "/data/data/<package name>/lib"
4553              * if we got here without anyone telling us different (e.g., apps
4554              * stored on SD card have their native libraries stored in the ASEC
4555              * container with the APK).
4556              *
4557              * This happens during an upgrade from a package settings file that
4558              * doesn't have a native library path attribute at all.
4559              */
4560             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
4561                 if (pkgSetting.nativeLibraryPathString == null) {
4562                     setInternalAppNativeLibraryPath(pkg, pkgSetting);
4563                 } else {
4564                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
4565                 }
4566             }
4567 
4568             pkgSetting.uidError = uidError;
4569         }
4570 
4571         String path = scanFile.getPath();
4572         /* Note: We don't want to unpack the native binaries for
4573          *        system applications, unless they have been updated
4574          *        (the binaries are already under /system/lib).
4575          *        Also, don't unpack libs for apps on the external card
4576          *        since they should have their libraries in the ASEC
4577          *        container already.
4578          *
4579          *        In other words, we're going to unpack the binaries
4580          *        only for non-system apps and system app upgrades.
4581          */
4582         if (pkg.applicationInfo.nativeLibraryDir != null) {
4583             try {
4584                 File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
4585                 final String dataPathString = dataPath.getCanonicalPath();
4586 
4587                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4588                     /*
4589                      * Upgrading from a previous version of the OS sometimes
4590                      * leaves native libraries in the /data/data/<app>/lib
4591                      * directory for system apps even when they shouldn't be.
4592                      * Recent changes in the JNI library search path
4593                      * necessitates we remove those to match previous behavior.
4594                      */
4595                     if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
4596                         Log.i(TAG, "removed obsolete native libraries for system package "
4597                                 + path);
4598                     }
4599                 } else {
4600                     if (!isForwardLocked(pkg) && !isExternal(pkg)) {
4601                         /*
4602                          * Update native library dir if it starts with
4603                          * /data/data
4604                          */
4605                         if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
4606                             setInternalAppNativeLibraryPath(pkg, pkgSetting);
4607                             nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
4608                         }
4609 
4610                         try {
4611                             if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
4612                                 Slog.e(TAG, "Unable to copy native libraries");
4613                                 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4614                                 return null;
4615                             }
4616                         } catch (IOException e) {
4617                             Slog.e(TAG, "Unable to copy native libraries", e);
4618                             mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4619                             return null;
4620                         }
4621                     }
4622 
4623                     if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
4624                     final int[] userIds = sUserManager.getUserIds();
4625                     synchronized (mInstallLock) {
4626                         for (int userId : userIds) {
4627                             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
4628                                     pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
4629                                 Slog.w(TAG, "Failed linking native library dir (user=" + userId
4630                                         + ")");
4631                                 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4632                                 return null;
4633                             }
4634                         }
4635                     }
4636                 }
4637             } catch (IOException ioe) {
4638                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
4639             }
4640         }
4641         pkg.mScanPath = path;
4642 
4643         if ((scanMode&SCAN_NO_DEX) == 0) {
4644             if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
4645                     == DEX_OPT_FAILED) {
4646                 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
4647                     removeDataDirsLI(pkg.packageName);
4648                 }
4649 
4650                 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
4651                 return null;
4652             }
4653         }
4654 
4655         if (mFactoryTest && pkg.requestedPermissions.contains(
4656                 android.Manifest.permission.FACTORY_TEST)) {
4657             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
4658         }
4659 
4660         ArrayList<PackageParser.Package> clientLibPkgs = null;
4661 
4662         // writer
4663         synchronized (mPackages) {
4664             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
4665                 // Only system apps can add new shared libraries.
4666                 if (pkg.libraryNames != null) {
4667                     for (int i=0; i<pkg.libraryNames.size(); i++) {
4668                         String name = pkg.libraryNames.get(i);
4669                         boolean allowed = false;
4670                         if (isUpdatedSystemApp(pkg)) {
4671                             // New library entries can only be added through the
4672                             // system image.  This is important to get rid of a lot
4673                             // of nasty edge cases: for example if we allowed a non-
4674                             // system update of the app to add a library, then uninstalling
4675                             // the update would make the library go away, and assumptions
4676                             // we made such as through app install filtering would now
4677                             // have allowed apps on the device which aren't compatible
4678                             // with it.  Better to just have the restriction here, be
4679                             // conservative, and create many fewer cases that can negatively
4680                             // impact the user experience.
4681                             final PackageSetting sysPs = mSettings
4682                                     .getDisabledSystemPkgLPr(pkg.packageName);
4683                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
4684                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
4685                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
4686                                         allowed = true;
4687                                         allowed = true;
4688                                         break;
4689                                     }
4690                                 }
4691                             }
4692                         } else {
4693                             allowed = true;
4694                         }
4695                         if (allowed) {
4696                             if (!mSharedLibraries.containsKey(name)) {
4697                                 mSharedLibraries.put(name, new SharedLibraryEntry(null,
4698                                         pkg.packageName));
4699                             } else if (!name.equals(pkg.packageName)) {
4700                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
4701                                         + name + " already exists; skipping");
4702                             }
4703                         } else {
4704                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
4705                                     + name + " that is not declared on system image; skipping");
4706                         }
4707                     }
4708                     if ((scanMode&SCAN_BOOTING) == 0) {
4709                         // If we are not booting, we need to update any applications
4710                         // that are clients of our shared library.  If we are booting,
4711                         // this will all be done once the scan is complete.
4712                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
4713                     }
4714                 }
4715             }
4716         }
4717 
4718         // We also need to dexopt any apps that are dependent on this library.  Note that
4719         // if these fail, we should abort the install since installing the library will
4720         // result in some apps being broken.
4721         if (clientLibPkgs != null) {
4722             if ((scanMode&SCAN_NO_DEX) == 0) {
4723                 for (int i=0; i<clientLibPkgs.size(); i++) {
4724                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
4725                     if (performDexOptLI(clientPkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
4726                             == DEX_OPT_FAILED) {
4727                         if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
4728                             removeDataDirsLI(pkg.packageName);
4729                         }
4730 
4731                         mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
4732                         return null;
4733                     }
4734                 }
4735             }
4736         }
4737 
4738         // Request the ActivityManager to kill the process(only for existing packages)
4739         // so that we do not end up in a confused state while the user is still using the older
4740         // version of the application while the new one gets installed.
4741         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
4742             // If the package lives in an asec, tell everyone that the container is going
4743             // away so they can clean up any references to its resources (which would prevent
4744             // vold from being able to unmount the asec)
4745             if (isForwardLocked(pkg) || isExternal(pkg)) {
4746                 if (DEBUG_INSTALL) {
4747                     Slog.i(TAG, "upgrading pkg " + pkg + " is ASEC-hosted -> UNAVAILABLE");
4748                 }
4749                 final int[] uidArray = new int[] { pkg.applicationInfo.uid };
4750                 final ArrayList<String> pkgList = new ArrayList<String>(1);
4751                 pkgList.add(pkg.applicationInfo.packageName);
4752                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
4753             }
4754 
4755             // Post the request that it be killed now that the going-away broadcast is en route
4756             killApplication(pkg.applicationInfo.packageName,
4757                         pkg.applicationInfo.uid, "update pkg");
4758         }
4759 
4760         // Also need to kill any apps that are dependent on the library.
4761         if (clientLibPkgs != null) {
4762             for (int i=0; i<clientLibPkgs.size(); i++) {
4763                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
4764                 killApplication(clientPkg.applicationInfo.packageName,
4765                         clientPkg.applicationInfo.uid, "update lib");
4766             }
4767         }
4768 
4769         // writer
4770         synchronized (mPackages) {
4771             // We don't expect installation to fail beyond this point,
4772             if ((scanMode&SCAN_MONITOR) != 0) {
4773                 mAppDirs.put(pkg.mPath, pkg);
4774             }
4775             // Add the new setting to mSettings
4776             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
4777             // Add the new setting to mPackages
4778             mPackages.put(pkg.applicationInfo.packageName, pkg);
4779             // Make sure we don't accidentally delete its data.
4780             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
4781             while (iter.hasNext()) {
4782                 PackageCleanItem item = iter.next();
4783                 if (pkgName.equals(item.packageName)) {
4784                     iter.remove();
4785                 }
4786             }
4787 
4788             // Take care of first install / last update times.
4789             if (currentTime != 0) {
4790                 if (pkgSetting.firstInstallTime == 0) {
4791                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
4792                 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
4793                     pkgSetting.lastUpdateTime = currentTime;
4794                 }
4795             } else if (pkgSetting.firstInstallTime == 0) {
4796                 // We need *something*.  Take time time stamp of the file.
4797                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
4798             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
4799                 if (scanFileTime != pkgSetting.timeStamp) {
4800                     // A package on the system image has changed; consider this
4801                     // to be an update.
4802                     pkgSetting.lastUpdateTime = scanFileTime;
4803                 }
4804             }
4805 
4806             // Add the package's KeySets to the global KeySetManager
4807             KeySetManager ksm = mSettings.mKeySetManager;
4808             try {
4809                 ksm.addSigningKeySetToPackage(pkg.packageName, pkg.mSigningKeys);
4810                 if (pkg.mKeySetMapping != null) {
4811                     for (Map.Entry<String, Set<PublicKey>> entry : pkg.mKeySetMapping.entrySet()) {
4812                         if (entry.getValue() != null) {
4813                             ksm.addDefinedKeySetToPackage(pkg.packageName,
4814                                 entry.getValue(), entry.getKey());
4815                         }
4816                     }
4817                 }
4818             } catch (NullPointerException e) {
4819                 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
4820             } catch (IllegalArgumentException e) {
4821                 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
4822             }
4823 
4824             int N = pkg.providers.size();
4825             StringBuilder r = null;
4826             int i;
4827             for (i=0; i<N; i++) {
4828                 PackageParser.Provider p = pkg.providers.get(i);
4829                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
4830                         p.info.processName, pkg.applicationInfo.uid);
4831                 mProviders.addProvider(p);
4832                 p.syncable = p.info.isSyncable;
4833                 if (p.info.authority != null) {
4834                     String names[] = p.info.authority.split(";");
4835                     p.info.authority = null;
4836                     for (int j = 0; j < names.length; j++) {
4837                         if (j == 1 && p.syncable) {
4838                             // We only want the first authority for a provider to possibly be
4839                             // syncable, so if we already added this provider using a different
4840                             // authority clear the syncable flag. We copy the provider before
4841                             // changing it because the mProviders object contains a reference
4842                             // to a provider that we don't want to change.
4843                             // Only do this for the second authority since the resulting provider
4844                             // object can be the same for all future authorities for this provider.
4845                             p = new PackageParser.Provider(p);
4846                             p.syncable = false;
4847                         }
4848                         if (!mProvidersByAuthority.containsKey(names[j])) {
4849                             mProvidersByAuthority.put(names[j], p);
4850                             if (p.info.authority == null) {
4851                                 p.info.authority = names[j];
4852                             } else {
4853                                 p.info.authority = p.info.authority + ";" + names[j];
4854                             }
4855                             if (DEBUG_PACKAGE_SCANNING) {
4856                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4857                                     Log.d(TAG, "Registered content provider: " + names[j]
4858                                             + ", className = " + p.info.name + ", isSyncable = "
4859                                             + p.info.isSyncable);
4860                             }
4861                         } else {
4862                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
4863                             Slog.w(TAG, "Skipping provider name " + names[j] +
4864                                     " (in package " + pkg.applicationInfo.packageName +
4865                                     "): name already used by "
4866                                     + ((other != null && other.getComponentName() != null)
4867                                             ? other.getComponentName().getPackageName() : "?"));
4868                         }
4869                     }
4870                 }
4871                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4872                     if (r == null) {
4873                         r = new StringBuilder(256);
4874                     } else {
4875                         r.append(' ');
4876                     }
4877                     r.append(p.info.name);
4878                 }
4879             }
4880             if (r != null) {
4881                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
4882             }
4883 
4884             N = pkg.services.size();
4885             r = null;
4886             for (i=0; i<N; i++) {
4887                 PackageParser.Service s = pkg.services.get(i);
4888                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
4889                         s.info.processName, pkg.applicationInfo.uid);
4890                 mServices.addService(s);
4891                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4892                     if (r == null) {
4893                         r = new StringBuilder(256);
4894                     } else {
4895                         r.append(' ');
4896                     }
4897                     r.append(s.info.name);
4898                 }
4899             }
4900             if (r != null) {
4901                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
4902             }
4903 
4904             N = pkg.receivers.size();
4905             r = null;
4906             for (i=0; i<N; i++) {
4907                 PackageParser.Activity a = pkg.receivers.get(i);
4908                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4909                         a.info.processName, pkg.applicationInfo.uid);
4910                 mReceivers.addActivity(a, "receiver");
4911                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4912                     if (r == null) {
4913                         r = new StringBuilder(256);
4914                     } else {
4915                         r.append(' ');
4916                     }
4917                     r.append(a.info.name);
4918                 }
4919             }
4920             if (r != null) {
4921                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
4922             }
4923 
4924             N = pkg.activities.size();
4925             r = null;
4926             for (i=0; i<N; i++) {
4927                 PackageParser.Activity a = pkg.activities.get(i);
4928                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4929                         a.info.processName, pkg.applicationInfo.uid);
4930                 mActivities.addActivity(a, "activity");
4931                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4932                     if (r == null) {
4933                         r = new StringBuilder(256);
4934                     } else {
4935                         r.append(' ');
4936                     }
4937                     r.append(a.info.name);
4938                 }
4939             }
4940             if (r != null) {
4941                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
4942             }
4943 
4944             N = pkg.permissionGroups.size();
4945             r = null;
4946             for (i=0; i<N; i++) {
4947                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
4948                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
4949                 if (cur == null) {
4950                     mPermissionGroups.put(pg.info.name, pg);
4951                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4952                         if (r == null) {
4953                             r = new StringBuilder(256);
4954                         } else {
4955                             r.append(' ');
4956                         }
4957                         r.append(pg.info.name);
4958                     }
4959                 } else {
4960                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
4961                             + pg.info.packageName + " ignored: original from "
4962                             + cur.info.packageName);
4963                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4964                         if (r == null) {
4965                             r = new StringBuilder(256);
4966                         } else {
4967                             r.append(' ');
4968                         }
4969                         r.append("DUP:");
4970                         r.append(pg.info.name);
4971                     }
4972                 }
4973             }
4974             if (r != null) {
4975                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
4976             }
4977 
4978             N = pkg.permissions.size();
4979             r = null;
4980             for (i=0; i<N; i++) {
4981                 PackageParser.Permission p = pkg.permissions.get(i);
4982                 HashMap<String, BasePermission> permissionMap =
4983                         p.tree ? mSettings.mPermissionTrees
4984                         : mSettings.mPermissions;
4985                 p.group = mPermissionGroups.get(p.info.group);
4986                 if (p.info.group == null || p.group != null) {
4987                     BasePermission bp = permissionMap.get(p.info.name);
4988                     if (bp == null) {
4989                         bp = new BasePermission(p.info.name, p.info.packageName,
4990                                 BasePermission.TYPE_NORMAL);
4991                         permissionMap.put(p.info.name, bp);
4992                     }
4993                     if (bp.perm == null) {
4994                         if (bp.sourcePackage != null
4995                                 && !bp.sourcePackage.equals(p.info.packageName)) {
4996                             // If this is a permission that was formerly defined by a non-system
4997                             // app, but is now defined by a system app (following an upgrade),
4998                             // discard the previous declaration and consider the system's to be
4999                             // canonical.
5000                             if (isSystemApp(p.owner)) {
5001                                 Slog.i(TAG, "New decl " + p.owner + " of permission  "
5002                                         + p.info.name + " is system");
5003                                 bp.sourcePackage = null;
5004                             }
5005                         }
5006                         if (bp.sourcePackage == null
5007                                 || bp.sourcePackage.equals(p.info.packageName)) {
5008                             BasePermission tree = findPermissionTreeLP(p.info.name);
5009                             if (tree == null
5010                                     || tree.sourcePackage.equals(p.info.packageName)) {
5011                                 bp.packageSetting = pkgSetting;
5012                                 bp.perm = p;
5013                                 bp.uid = pkg.applicationInfo.uid;
5014                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5015                                     if (r == null) {
5016                                         r = new StringBuilder(256);
5017                                     } else {
5018                                         r.append(' ');
5019                                     }
5020                                     r.append(p.info.name);
5021                                 }
5022                             } else {
5023                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
5024                                         + p.info.packageName + " ignored: base tree "
5025                                         + tree.name + " is from package "
5026                                         + tree.sourcePackage);
5027                             }
5028                         } else {
5029                             Slog.w(TAG, "Permission " + p.info.name + " from package "
5030                                     + p.info.packageName + " ignored: original from "
5031                                     + bp.sourcePackage);
5032                         }
5033                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5034                         if (r == null) {
5035                             r = new StringBuilder(256);
5036                         } else {
5037                             r.append(' ');
5038                         }
5039                         r.append("DUP:");
5040                         r.append(p.info.name);
5041                     }
5042                     if (bp.perm == p) {
5043                         bp.protectionLevel = p.info.protectionLevel;
5044                     }
5045                 } else {
5046                     Slog.w(TAG, "Permission " + p.info.name + " from package "
5047                             + p.info.packageName + " ignored: no group "
5048                             + p.group);
5049                 }
5050             }
5051             if (r != null) {
5052                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
5053             }
5054 
5055             N = pkg.instrumentation.size();
5056             r = null;
5057             for (i=0; i<N; i++) {
5058                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
5059                 a.info.packageName = pkg.applicationInfo.packageName;
5060                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
5061                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
5062                 a.info.dataDir = pkg.applicationInfo.dataDir;
5063                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
5064                 mInstrumentation.put(a.getComponentName(), a);
5065                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
5066                     if (r == null) {
5067                         r = new StringBuilder(256);
5068                     } else {
5069                         r.append(' ');
5070                     }
5071                     r.append(a.info.name);
5072                 }
5073             }
5074             if (r != null) {
5075                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
5076             }
5077 
5078             if (pkg.protectedBroadcasts != null) {
5079                 N = pkg.protectedBroadcasts.size();
5080                 for (i=0; i<N; i++) {
5081                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
5082                 }
5083             }
5084 
5085             pkgSetting.setTimeStamp(scanFileTime);
5086         }
5087 
5088         return pkg;
5089     }
5090 
setUpCustomResolverActivity(PackageParser.Package pkg)5091     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
5092         synchronized (mPackages) {
5093             mResolverReplaced = true;
5094             // Set up information for custom user intent resolution activity.
5095             mResolveActivity.applicationInfo = pkg.applicationInfo;
5096             mResolveActivity.name = mCustomResolverComponentName.getClassName();
5097             mResolveActivity.packageName = pkg.applicationInfo.packageName;
5098             mResolveActivity.processName = null;
5099             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5100             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
5101                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
5102             mResolveActivity.theme = 0;
5103             mResolveActivity.exported = true;
5104             mResolveActivity.enabled = true;
5105             mResolveInfo.activityInfo = mResolveActivity;
5106             mResolveInfo.priority = 0;
5107             mResolveInfo.preferredOrder = 0;
5108             mResolveInfo.match = 0;
5109             mResolveComponentName = mCustomResolverComponentName;
5110             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
5111                     mResolveComponentName);
5112         }
5113     }
5114 
setInternalAppNativeLibraryPath(PackageParser.Package pkg, PackageSetting pkgSetting)5115     private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
5116             PackageSetting pkgSetting) {
5117         final String apkLibPath = getApkName(pkgSetting.codePathString);
5118         final String nativeLibraryPath = new File(mAppLibInstallDir, apkLibPath).getPath();
5119         pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
5120         pkgSetting.nativeLibraryPathString = nativeLibraryPath;
5121     }
5122 
copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)5123     private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
5124             throws IOException {
5125         if (!nativeLibraryDir.isDirectory()) {
5126             nativeLibraryDir.delete();
5127 
5128             if (!nativeLibraryDir.mkdir()) {
5129                 throw new IOException("Cannot create " + nativeLibraryDir.getPath());
5130             }
5131 
5132             try {
5133                 Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
5134                         | S_IXOTH);
5135             } catch (ErrnoException e) {
5136                 throw new IOException("Cannot chmod native library directory "
5137                         + nativeLibraryDir.getPath(), e);
5138             }
5139         } else if (!SELinux.restorecon(nativeLibraryDir)) {
5140             throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath());
5141         }
5142 
5143         /*
5144          * If this is an internal application or our nativeLibraryPath points to
5145          * the app-lib directory, unpack the libraries if necessary.
5146          */
5147         return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
5148     }
5149 
killApplication(String pkgName, int appId, String reason)5150     private void killApplication(String pkgName, int appId, String reason) {
5151         // Request the ActivityManager to kill the process(only for existing packages)
5152         // so that we do not end up in a confused state while the user is still using the older
5153         // version of the application while the new one gets installed.
5154         IActivityManager am = ActivityManagerNative.getDefault();
5155         if (am != null) {
5156             try {
5157                 am.killApplicationWithAppId(pkgName, appId, reason);
5158             } catch (RemoteException e) {
5159             }
5160         }
5161     }
5162 
removePackageLI(PackageSetting ps, boolean chatty)5163     void removePackageLI(PackageSetting ps, boolean chatty) {
5164         if (DEBUG_INSTALL) {
5165             if (chatty)
5166                 Log.d(TAG, "Removing package " + ps.name);
5167         }
5168 
5169         // writer
5170         synchronized (mPackages) {
5171             mPackages.remove(ps.name);
5172             if (ps.codePathString != null) {
5173                 mAppDirs.remove(ps.codePathString);
5174             }
5175 
5176             final PackageParser.Package pkg = ps.pkg;
5177             if (pkg != null) {
5178                 cleanPackageDataStructuresLILPw(pkg, chatty);
5179             }
5180         }
5181     }
5182 
removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)5183     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
5184         if (DEBUG_INSTALL) {
5185             if (chatty)
5186                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
5187         }
5188 
5189         // writer
5190         synchronized (mPackages) {
5191             mPackages.remove(pkg.applicationInfo.packageName);
5192             if (pkg.mPath != null) {
5193                 mAppDirs.remove(pkg.mPath);
5194             }
5195             cleanPackageDataStructuresLILPw(pkg, chatty);
5196         }
5197     }
5198 
cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)5199     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
5200         int N = pkg.providers.size();
5201         StringBuilder r = null;
5202         int i;
5203         for (i=0; i<N; i++) {
5204             PackageParser.Provider p = pkg.providers.get(i);
5205             mProviders.removeProvider(p);
5206             if (p.info.authority == null) {
5207 
5208                 /* There was another ContentProvider with this authority when
5209                  * this app was installed so this authority is null,
5210                  * Ignore it as we don't have to unregister the provider.
5211                  */
5212                 continue;
5213             }
5214             String names[] = p.info.authority.split(";");
5215             for (int j = 0; j < names.length; j++) {
5216                 if (mProvidersByAuthority.get(names[j]) == p) {
5217                     mProvidersByAuthority.remove(names[j]);
5218                     if (DEBUG_REMOVE) {
5219                         if (chatty)
5220                             Log.d(TAG, "Unregistered content provider: " + names[j]
5221                                     + ", className = " + p.info.name + ", isSyncable = "
5222                                     + p.info.isSyncable);
5223                     }
5224                 }
5225             }
5226             if (DEBUG_REMOVE && chatty) {
5227                 if (r == null) {
5228                     r = new StringBuilder(256);
5229                 } else {
5230                     r.append(' ');
5231                 }
5232                 r.append(p.info.name);
5233             }
5234         }
5235         if (r != null) {
5236             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
5237         }
5238 
5239         N = pkg.services.size();
5240         r = null;
5241         for (i=0; i<N; i++) {
5242             PackageParser.Service s = pkg.services.get(i);
5243             mServices.removeService(s);
5244             if (chatty) {
5245                 if (r == null) {
5246                     r = new StringBuilder(256);
5247                 } else {
5248                     r.append(' ');
5249                 }
5250                 r.append(s.info.name);
5251             }
5252         }
5253         if (r != null) {
5254             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
5255         }
5256 
5257         N = pkg.receivers.size();
5258         r = null;
5259         for (i=0; i<N; i++) {
5260             PackageParser.Activity a = pkg.receivers.get(i);
5261             mReceivers.removeActivity(a, "receiver");
5262             if (DEBUG_REMOVE && chatty) {
5263                 if (r == null) {
5264                     r = new StringBuilder(256);
5265                 } else {
5266                     r.append(' ');
5267                 }
5268                 r.append(a.info.name);
5269             }
5270         }
5271         if (r != null) {
5272             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
5273         }
5274 
5275         N = pkg.activities.size();
5276         r = null;
5277         for (i=0; i<N; i++) {
5278             PackageParser.Activity a = pkg.activities.get(i);
5279             mActivities.removeActivity(a, "activity");
5280             if (DEBUG_REMOVE && chatty) {
5281                 if (r == null) {
5282                     r = new StringBuilder(256);
5283                 } else {
5284                     r.append(' ');
5285                 }
5286                 r.append(a.info.name);
5287             }
5288         }
5289         if (r != null) {
5290             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
5291         }
5292 
5293         N = pkg.permissions.size();
5294         r = null;
5295         for (i=0; i<N; i++) {
5296             PackageParser.Permission p = pkg.permissions.get(i);
5297             BasePermission bp = mSettings.mPermissions.get(p.info.name);
5298             if (bp == null) {
5299                 bp = mSettings.mPermissionTrees.get(p.info.name);
5300             }
5301             if (bp != null && bp.perm == p) {
5302                 bp.perm = null;
5303                 if (DEBUG_REMOVE && chatty) {
5304                     if (r == null) {
5305                         r = new StringBuilder(256);
5306                     } else {
5307                         r.append(' ');
5308                     }
5309                     r.append(p.info.name);
5310                 }
5311             }
5312         }
5313         if (r != null) {
5314             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
5315         }
5316 
5317         N = pkg.instrumentation.size();
5318         r = null;
5319         for (i=0; i<N; i++) {
5320             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
5321             mInstrumentation.remove(a.getComponentName());
5322             if (DEBUG_REMOVE && chatty) {
5323                 if (r == null) {
5324                     r = new StringBuilder(256);
5325                 } else {
5326                     r.append(' ');
5327                 }
5328                 r.append(a.info.name);
5329             }
5330         }
5331         if (r != null) {
5332             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
5333         }
5334 
5335         r = null;
5336         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5337             // Only system apps can hold shared libraries.
5338             if (pkg.libraryNames != null) {
5339                 for (i=0; i<pkg.libraryNames.size(); i++) {
5340                     String name = pkg.libraryNames.get(i);
5341                     SharedLibraryEntry cur = mSharedLibraries.get(name);
5342                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
5343                         mSharedLibraries.remove(name);
5344                         if (DEBUG_REMOVE && chatty) {
5345                             if (r == null) {
5346                                 r = new StringBuilder(256);
5347                             } else {
5348                                 r.append(' ');
5349                             }
5350                             r.append(name);
5351                         }
5352                     }
5353                 }
5354             }
5355         }
5356         if (r != null) {
5357             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
5358         }
5359     }
5360 
isPackageFilename(String name)5361     private static final boolean isPackageFilename(String name) {
5362         return name != null && name.endsWith(".apk");
5363     }
5364 
hasPermission(PackageParser.Package pkgInfo, String perm)5365     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
5366         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
5367             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
5368                 return true;
5369             }
5370         }
5371         return false;
5372     }
5373 
5374     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
5375     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
5376     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
5377 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)5378     private void updatePermissionsLPw(String changingPkg,
5379             PackageParser.Package pkgInfo, int flags) {
5380         // Make sure there are no dangling permission trees.
5381         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
5382         while (it.hasNext()) {
5383             final BasePermission bp = it.next();
5384             if (bp.packageSetting == null) {
5385                 // We may not yet have parsed the package, so just see if
5386                 // we still know about its settings.
5387                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5388             }
5389             if (bp.packageSetting == null) {
5390                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
5391                         + " from package " + bp.sourcePackage);
5392                 it.remove();
5393             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5394                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5395                     Slog.i(TAG, "Removing old permission tree: " + bp.name
5396                             + " from package " + bp.sourcePackage);
5397                     flags |= UPDATE_PERMISSIONS_ALL;
5398                     it.remove();
5399                 }
5400             }
5401         }
5402 
5403         // Make sure all dynamic permissions have been assigned to a package,
5404         // and make sure there are no dangling permissions.
5405         it = mSettings.mPermissions.values().iterator();
5406         while (it.hasNext()) {
5407             final BasePermission bp = it.next();
5408             if (bp.type == BasePermission.TYPE_DYNAMIC) {
5409                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
5410                         + bp.name + " pkg=" + bp.sourcePackage
5411                         + " info=" + bp.pendingInfo);
5412                 if (bp.packageSetting == null && bp.pendingInfo != null) {
5413                     final BasePermission tree = findPermissionTreeLP(bp.name);
5414                     if (tree != null && tree.perm != null) {
5415                         bp.packageSetting = tree.packageSetting;
5416                         bp.perm = new PackageParser.Permission(tree.perm.owner,
5417                                 new PermissionInfo(bp.pendingInfo));
5418                         bp.perm.info.packageName = tree.perm.info.packageName;
5419                         bp.perm.info.name = bp.name;
5420                         bp.uid = tree.uid;
5421                     }
5422                 }
5423             }
5424             if (bp.packageSetting == null) {
5425                 // We may not yet have parsed the package, so just see if
5426                 // we still know about its settings.
5427                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5428             }
5429             if (bp.packageSetting == null) {
5430                 Slog.w(TAG, "Removing dangling permission: " + bp.name
5431                         + " from package " + bp.sourcePackage);
5432                 it.remove();
5433             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5434                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5435                     Slog.i(TAG, "Removing old permission: " + bp.name
5436                             + " from package " + bp.sourcePackage);
5437                     flags |= UPDATE_PERMISSIONS_ALL;
5438                     it.remove();
5439                 }
5440             }
5441         }
5442 
5443         // Now update the permissions for all packages, in particular
5444         // replace the granted permissions of the system packages.
5445         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
5446             for (PackageParser.Package pkg : mPackages.values()) {
5447                 if (pkg != pkgInfo) {
5448                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
5449                 }
5450             }
5451         }
5452 
5453         if (pkgInfo != null) {
5454             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
5455         }
5456     }
5457 
grantPermissionsLPw(PackageParser.Package pkg, boolean replace)5458     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
5459         final PackageSetting ps = (PackageSetting) pkg.mExtras;
5460         if (ps == null) {
5461             return;
5462         }
5463         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
5464         HashSet<String> origPermissions = gp.grantedPermissions;
5465         boolean changedPermission = false;
5466 
5467         if (replace) {
5468             ps.permissionsFixed = false;
5469             if (gp == ps) {
5470                 origPermissions = new HashSet<String>(gp.grantedPermissions);
5471                 gp.grantedPermissions.clear();
5472                 gp.gids = mGlobalGids;
5473             }
5474         }
5475 
5476         if (gp.gids == null) {
5477             gp.gids = mGlobalGids;
5478         }
5479 
5480         final int N = pkg.requestedPermissions.size();
5481         for (int i=0; i<N; i++) {
5482             final String name = pkg.requestedPermissions.get(i);
5483             final boolean required = pkg.requestedPermissionsRequired.get(i);
5484             final BasePermission bp = mSettings.mPermissions.get(name);
5485             if (DEBUG_INSTALL) {
5486                 if (gp != ps) {
5487                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
5488                 }
5489             }
5490 
5491             if (bp == null || bp.packageSetting == null) {
5492                 Slog.w(TAG, "Unknown permission " + name
5493                         + " in package " + pkg.packageName);
5494                 continue;
5495             }
5496 
5497             final String perm = bp.name;
5498             boolean allowed;
5499             boolean allowedSig = false;
5500             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
5501             if (level == PermissionInfo.PROTECTION_NORMAL
5502                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
5503                 // We grant a normal or dangerous permission if any of the following
5504                 // are true:
5505                 // 1) The permission is required
5506                 // 2) The permission is optional, but was granted in the past
5507                 // 3) The permission is optional, but was requested by an
5508                 //    app in /system (not /data)
5509                 //
5510                 // Otherwise, reject the permission.
5511                 allowed = (required || origPermissions.contains(perm)
5512                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
5513             } else if (bp.packageSetting == null) {
5514                 // This permission is invalid; skip it.
5515                 allowed = false;
5516             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
5517                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
5518                 if (allowed) {
5519                     allowedSig = true;
5520                 }
5521             } else {
5522                 allowed = false;
5523             }
5524             if (DEBUG_INSTALL) {
5525                 if (gp != ps) {
5526                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
5527                 }
5528             }
5529             if (allowed) {
5530                 if (!isSystemApp(ps) && ps.permissionsFixed) {
5531                     // If this is an existing, non-system package, then
5532                     // we can't add any new permissions to it.
5533                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
5534                         // Except...  if this is a permission that was added
5535                         // to the platform (note: need to only do this when
5536                         // updating the platform).
5537                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
5538                     }
5539                 }
5540                 if (allowed) {
5541                     if (!gp.grantedPermissions.contains(perm)) {
5542                         changedPermission = true;
5543                         gp.grantedPermissions.add(perm);
5544                         gp.gids = appendInts(gp.gids, bp.gids);
5545                     } else if (!ps.haveGids) {
5546                         gp.gids = appendInts(gp.gids, bp.gids);
5547                     }
5548                 } else {
5549                     Slog.w(TAG, "Not granting permission " + perm
5550                             + " to package " + pkg.packageName
5551                             + " because it was previously installed without");
5552                 }
5553             } else {
5554                 if (gp.grantedPermissions.remove(perm)) {
5555                     changedPermission = true;
5556                     gp.gids = removeInts(gp.gids, bp.gids);
5557                     Slog.i(TAG, "Un-granting permission " + perm
5558                             + " from package " + pkg.packageName
5559                             + " (protectionLevel=" + bp.protectionLevel
5560                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
5561                             + ")");
5562                 } else {
5563                     Slog.w(TAG, "Not granting permission " + perm
5564                             + " to package " + pkg.packageName
5565                             + " (protectionLevel=" + bp.protectionLevel
5566                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
5567                             + ")");
5568                 }
5569             }
5570         }
5571 
5572         if ((changedPermission || replace) && !ps.permissionsFixed &&
5573                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
5574             // This is the first that we have heard about this package, so the
5575             // permissions we have now selected are fixed until explicitly
5576             // changed.
5577             ps.permissionsFixed = true;
5578         }
5579         ps.haveGids = true;
5580     }
5581 
isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)5582     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
5583         boolean allowed = false;
5584         final int NP = PackageParser.NEW_PERMISSIONS.length;
5585         for (int ip=0; ip<NP; ip++) {
5586             final PackageParser.NewPermissionInfo npi
5587                     = PackageParser.NEW_PERMISSIONS[ip];
5588             if (npi.name.equals(perm)
5589                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
5590                 allowed = true;
5591                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
5592                         + pkg.packageName);
5593                 break;
5594             }
5595         }
5596         return allowed;
5597     }
5598 
grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, HashSet<String> origPermissions)5599     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
5600                                           BasePermission bp, HashSet<String> origPermissions) {
5601         boolean allowed;
5602         allowed = (compareSignatures(
5603                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
5604                         == PackageManager.SIGNATURE_MATCH)
5605                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
5606                         == PackageManager.SIGNATURE_MATCH);
5607         if (!allowed && (bp.protectionLevel
5608                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
5609             if (isSystemApp(pkg)) {
5610                 // For updated system applications, a system permission
5611                 // is granted only if it had been defined by the original application.
5612                 if (isUpdatedSystemApp(pkg)) {
5613                     final PackageSetting sysPs = mSettings
5614                             .getDisabledSystemPkgLPr(pkg.packageName);
5615                     final GrantedPermissions origGp = sysPs.sharedUser != null
5616                             ? sysPs.sharedUser : sysPs;
5617 
5618                     if (origGp.grantedPermissions.contains(perm)) {
5619                         // If the original was granted this permission, we take
5620                         // that grant decision as read and propagate it to the
5621                         // update.
5622                         allowed = true;
5623                     } else {
5624                         // The system apk may have been updated with an older
5625                         // version of the one on the data partition, but which
5626                         // granted a new system permission that it didn't have
5627                         // before.  In this case we do want to allow the app to
5628                         // now get the new permission if the ancestral apk is
5629                         // privileged to get it.
5630                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
5631                             for (int j=0;
5632                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
5633                                 if (perm.equals(
5634                                         sysPs.pkg.requestedPermissions.get(j))) {
5635                                     allowed = true;
5636                                     break;
5637                                 }
5638                             }
5639                         }
5640                     }
5641                 } else {
5642                     allowed = isPrivilegedApp(pkg);
5643                 }
5644             }
5645         }
5646         if (!allowed && (bp.protectionLevel
5647                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
5648             // For development permissions, a development permission
5649             // is granted only if it was already granted.
5650             allowed = origPermissions.contains(perm);
5651         }
5652         return allowed;
5653     }
5654 
5655     final class ActivityIntentResolver
5656             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)5657         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
5658                 boolean defaultOnly, int userId) {
5659             if (!sUserManager.exists(userId)) return null;
5660             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
5661             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
5662         }
5663 
queryIntent(Intent intent, String resolvedType, int flags, int userId)5664         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
5665                 int userId) {
5666             if (!sUserManager.exists(userId)) return null;
5667             mFlags = flags;
5668             return super.queryIntent(intent, resolvedType,
5669                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
5670         }
5671 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)5672         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
5673                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
5674             if (!sUserManager.exists(userId)) return null;
5675             if (packageActivities == null) {
5676                 return null;
5677             }
5678             mFlags = flags;
5679             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
5680             final int N = packageActivities.size();
5681             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
5682                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
5683 
5684             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
5685             for (int i = 0; i < N; ++i) {
5686                 intentFilters = packageActivities.get(i).intents;
5687                 if (intentFilters != null && intentFilters.size() > 0) {
5688                     PackageParser.ActivityIntentInfo[] array =
5689                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
5690                     intentFilters.toArray(array);
5691                     listCut.add(array);
5692                 }
5693             }
5694             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
5695         }
5696 
addActivity(PackageParser.Activity a, String type)5697         public final void addActivity(PackageParser.Activity a, String type) {
5698             final boolean systemApp = isSystemApp(a.info.applicationInfo);
5699             mActivities.put(a.getComponentName(), a);
5700             if (DEBUG_SHOW_INFO)
5701                 Log.v(
5702                 TAG, "  " + type + " " +
5703                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
5704             if (DEBUG_SHOW_INFO)
5705                 Log.v(TAG, "    Class=" + a.info.name);
5706             final int NI = a.intents.size();
5707             for (int j=0; j<NI; j++) {
5708                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
5709                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
5710                     intent.setPriority(0);
5711                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
5712                             + a.className + " with priority > 0, forcing to 0");
5713                 }
5714                 if (DEBUG_SHOW_INFO) {
5715                     Log.v(TAG, "    IntentFilter:");
5716                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5717                 }
5718                 if (!intent.debugCheck()) {
5719                     Log.w(TAG, "==> For Activity " + a.info.name);
5720                 }
5721                 addFilter(intent);
5722             }
5723         }
5724 
removeActivity(PackageParser.Activity a, String type)5725         public final void removeActivity(PackageParser.Activity a, String type) {
5726             mActivities.remove(a.getComponentName());
5727             if (DEBUG_SHOW_INFO) {
5728                 Log.v(TAG, "  " + type + " "
5729                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
5730                                 : a.info.name) + ":");
5731                 Log.v(TAG, "    Class=" + a.info.name);
5732             }
5733             final int NI = a.intents.size();
5734             for (int j=0; j<NI; j++) {
5735                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
5736                 if (DEBUG_SHOW_INFO) {
5737                     Log.v(TAG, "    IntentFilter:");
5738                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5739                 }
5740                 removeFilter(intent);
5741             }
5742         }
5743 
5744         @Override
allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)5745         protected boolean allowFilterResult(
5746                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
5747             ActivityInfo filterAi = filter.activity.info;
5748             for (int i=dest.size()-1; i>=0; i--) {
5749                 ActivityInfo destAi = dest.get(i).activityInfo;
5750                 if (destAi.name == filterAi.name
5751                         && destAi.packageName == filterAi.packageName) {
5752                     return false;
5753                 }
5754             }
5755             return true;
5756         }
5757 
5758         @Override
newArray(int size)5759         protected ActivityIntentInfo[] newArray(int size) {
5760             return new ActivityIntentInfo[size];
5761         }
5762 
5763         @Override
isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)5764         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
5765             if (!sUserManager.exists(userId)) return true;
5766             PackageParser.Package p = filter.activity.owner;
5767             if (p != null) {
5768                 PackageSetting ps = (PackageSetting)p.mExtras;
5769                 if (ps != null) {
5770                     // System apps are never considered stopped for purposes of
5771                     // filtering, because there may be no way for the user to
5772                     // actually re-launch them.
5773                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
5774                             && ps.getStopped(userId);
5775                 }
5776             }
5777             return false;
5778         }
5779 
5780         @Override
isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)5781         protected boolean isPackageForFilter(String packageName,
5782                 PackageParser.ActivityIntentInfo info) {
5783             return packageName.equals(info.activity.owner.packageName);
5784         }
5785 
5786         @Override
newResult(PackageParser.ActivityIntentInfo info, int match, int userId)5787         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
5788                 int match, int userId) {
5789             if (!sUserManager.exists(userId)) return null;
5790             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
5791                 return null;
5792             }
5793             final PackageParser.Activity activity = info.activity;
5794             if (mSafeMode && (activity.info.applicationInfo.flags
5795                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
5796                 return null;
5797             }
5798             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
5799             if (ps == null) {
5800                 return null;
5801             }
5802             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
5803                     ps.readUserState(userId), userId);
5804             if (ai == null) {
5805                 return null;
5806             }
5807             final ResolveInfo res = new ResolveInfo();
5808             res.activityInfo = ai;
5809             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
5810                 res.filter = info;
5811             }
5812             res.priority = info.getPriority();
5813             res.preferredOrder = activity.owner.mPreferredOrder;
5814             //System.out.println("Result: " + res.activityInfo.className +
5815             //                   " = " + res.priority);
5816             res.match = match;
5817             res.isDefault = info.hasDefault;
5818             res.labelRes = info.labelRes;
5819             res.nonLocalizedLabel = info.nonLocalizedLabel;
5820             res.icon = info.icon;
5821             res.system = isSystemApp(res.activityInfo.applicationInfo);
5822             return res;
5823         }
5824 
5825         @Override
sortResults(List<ResolveInfo> results)5826         protected void sortResults(List<ResolveInfo> results) {
5827             Collections.sort(results, mResolvePrioritySorter);
5828         }
5829 
5830         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)5831         protected void dumpFilter(PrintWriter out, String prefix,
5832                 PackageParser.ActivityIntentInfo filter) {
5833             out.print(prefix); out.print(
5834                     Integer.toHexString(System.identityHashCode(filter.activity)));
5835                     out.print(' ');
5836                     filter.activity.printComponentShortName(out);
5837                     out.print(" filter ");
5838                     out.println(Integer.toHexString(System.identityHashCode(filter)));
5839         }
5840 
5841 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
5842 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
5843 //            final List<ResolveInfo> retList = Lists.newArrayList();
5844 //            while (i.hasNext()) {
5845 //                final ResolveInfo resolveInfo = i.next();
5846 //                if (isEnabledLP(resolveInfo.activityInfo)) {
5847 //                    retList.add(resolveInfo);
5848 //                }
5849 //            }
5850 //            return retList;
5851 //        }
5852 
5853         // Keys are String (activity class name), values are Activity.
5854         private final HashMap<ComponentName, PackageParser.Activity> mActivities
5855                 = new HashMap<ComponentName, PackageParser.Activity>();
5856         private int mFlags;
5857     }
5858 
5859     private final class ServiceIntentResolver
5860             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)5861         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
5862                 boolean defaultOnly, int userId) {
5863             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
5864             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
5865         }
5866 
queryIntent(Intent intent, String resolvedType, int flags, int userId)5867         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
5868                 int userId) {
5869             if (!sUserManager.exists(userId)) return null;
5870             mFlags = flags;
5871             return super.queryIntent(intent, resolvedType,
5872                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
5873         }
5874 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)5875         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
5876                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
5877             if (!sUserManager.exists(userId)) return null;
5878             if (packageServices == null) {
5879                 return null;
5880             }
5881             mFlags = flags;
5882             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
5883             final int N = packageServices.size();
5884             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
5885                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
5886 
5887             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
5888             for (int i = 0; i < N; ++i) {
5889                 intentFilters = packageServices.get(i).intents;
5890                 if (intentFilters != null && intentFilters.size() > 0) {
5891                     PackageParser.ServiceIntentInfo[] array =
5892                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
5893                     intentFilters.toArray(array);
5894                     listCut.add(array);
5895                 }
5896             }
5897             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
5898         }
5899 
addService(PackageParser.Service s)5900         public final void addService(PackageParser.Service s) {
5901             mServices.put(s.getComponentName(), s);
5902             if (DEBUG_SHOW_INFO) {
5903                 Log.v(TAG, "  "
5904                         + (s.info.nonLocalizedLabel != null
5905                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
5906                 Log.v(TAG, "    Class=" + s.info.name);
5907             }
5908             final int NI = s.intents.size();
5909             int j;
5910             for (j=0; j<NI; j++) {
5911                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5912                 if (DEBUG_SHOW_INFO) {
5913                     Log.v(TAG, "    IntentFilter:");
5914                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5915                 }
5916                 if (!intent.debugCheck()) {
5917                     Log.w(TAG, "==> For Service " + s.info.name);
5918                 }
5919                 addFilter(intent);
5920             }
5921         }
5922 
removeService(PackageParser.Service s)5923         public final void removeService(PackageParser.Service s) {
5924             mServices.remove(s.getComponentName());
5925             if (DEBUG_SHOW_INFO) {
5926                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
5927                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
5928                 Log.v(TAG, "    Class=" + s.info.name);
5929             }
5930             final int NI = s.intents.size();
5931             int j;
5932             for (j=0; j<NI; j++) {
5933                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5934                 if (DEBUG_SHOW_INFO) {
5935                     Log.v(TAG, "    IntentFilter:");
5936                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5937                 }
5938                 removeFilter(intent);
5939             }
5940         }
5941 
5942         @Override
allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)5943         protected boolean allowFilterResult(
5944                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
5945             ServiceInfo filterSi = filter.service.info;
5946             for (int i=dest.size()-1; i>=0; i--) {
5947                 ServiceInfo destAi = dest.get(i).serviceInfo;
5948                 if (destAi.name == filterSi.name
5949                         && destAi.packageName == filterSi.packageName) {
5950                     return false;
5951                 }
5952             }
5953             return true;
5954         }
5955 
5956         @Override
newArray(int size)5957         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
5958             return new PackageParser.ServiceIntentInfo[size];
5959         }
5960 
5961         @Override
isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)5962         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
5963             if (!sUserManager.exists(userId)) return true;
5964             PackageParser.Package p = filter.service.owner;
5965             if (p != null) {
5966                 PackageSetting ps = (PackageSetting)p.mExtras;
5967                 if (ps != null) {
5968                     // System apps are never considered stopped for purposes of
5969                     // filtering, because there may be no way for the user to
5970                     // actually re-launch them.
5971                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
5972                             && ps.getStopped(userId);
5973                 }
5974             }
5975             return false;
5976         }
5977 
5978         @Override
isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)5979         protected boolean isPackageForFilter(String packageName,
5980                 PackageParser.ServiceIntentInfo info) {
5981             return packageName.equals(info.service.owner.packageName);
5982         }
5983 
5984         @Override
newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)5985         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
5986                 int match, int userId) {
5987             if (!sUserManager.exists(userId)) return null;
5988             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
5989             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
5990                 return null;
5991             }
5992             final PackageParser.Service service = info.service;
5993             if (mSafeMode && (service.info.applicationInfo.flags
5994                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
5995                 return null;
5996             }
5997             PackageSetting ps = (PackageSetting) service.owner.mExtras;
5998             if (ps == null) {
5999                 return null;
6000             }
6001             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
6002                     ps.readUserState(userId), userId);
6003             if (si == null) {
6004                 return null;
6005             }
6006             final ResolveInfo res = new ResolveInfo();
6007             res.serviceInfo = si;
6008             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
6009                 res.filter = filter;
6010             }
6011             res.priority = info.getPriority();
6012             res.preferredOrder = service.owner.mPreferredOrder;
6013             //System.out.println("Result: " + res.activityInfo.className +
6014             //                   " = " + res.priority);
6015             res.match = match;
6016             res.isDefault = info.hasDefault;
6017             res.labelRes = info.labelRes;
6018             res.nonLocalizedLabel = info.nonLocalizedLabel;
6019             res.icon = info.icon;
6020             res.system = isSystemApp(res.serviceInfo.applicationInfo);
6021             return res;
6022         }
6023 
6024         @Override
sortResults(List<ResolveInfo> results)6025         protected void sortResults(List<ResolveInfo> results) {
6026             Collections.sort(results, mResolvePrioritySorter);
6027         }
6028 
6029         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)6030         protected void dumpFilter(PrintWriter out, String prefix,
6031                 PackageParser.ServiceIntentInfo filter) {
6032             out.print(prefix); out.print(
6033                     Integer.toHexString(System.identityHashCode(filter.service)));
6034                     out.print(' ');
6035                     filter.service.printComponentShortName(out);
6036                     out.print(" filter ");
6037                     out.println(Integer.toHexString(System.identityHashCode(filter)));
6038         }
6039 
6040 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
6041 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
6042 //            final List<ResolveInfo> retList = Lists.newArrayList();
6043 //            while (i.hasNext()) {
6044 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
6045 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
6046 //                    retList.add(resolveInfo);
6047 //                }
6048 //            }
6049 //            return retList;
6050 //        }
6051 
6052         // Keys are String (activity class name), values are Activity.
6053         private final HashMap<ComponentName, PackageParser.Service> mServices
6054                 = new HashMap<ComponentName, PackageParser.Service>();
6055         private int mFlags;
6056     };
6057 
6058     private final class ProviderIntentResolver
6059             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)6060         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
6061                 boolean defaultOnly, int userId) {
6062             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
6063             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
6064         }
6065 
queryIntent(Intent intent, String resolvedType, int flags, int userId)6066         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
6067                 int userId) {
6068             if (!sUserManager.exists(userId))
6069                 return null;
6070             mFlags = flags;
6071             return super.queryIntent(intent, resolvedType,
6072                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
6073         }
6074 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)6075         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
6076                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
6077             if (!sUserManager.exists(userId))
6078                 return null;
6079             if (packageProviders == null) {
6080                 return null;
6081             }
6082             mFlags = flags;
6083             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
6084             final int N = packageProviders.size();
6085             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
6086                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
6087 
6088             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
6089             for (int i = 0; i < N; ++i) {
6090                 intentFilters = packageProviders.get(i).intents;
6091                 if (intentFilters != null && intentFilters.size() > 0) {
6092                     PackageParser.ProviderIntentInfo[] array =
6093                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
6094                     intentFilters.toArray(array);
6095                     listCut.add(array);
6096                 }
6097             }
6098             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
6099         }
6100 
addProvider(PackageParser.Provider p)6101         public final void addProvider(PackageParser.Provider p) {
6102             mProviders.put(p.getComponentName(), p);
6103             if (DEBUG_SHOW_INFO) {
6104                 Log.v(TAG, "  "
6105                         + (p.info.nonLocalizedLabel != null
6106                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
6107                 Log.v(TAG, "    Class=" + p.info.name);
6108             }
6109             final int NI = p.intents.size();
6110             int j;
6111             for (j = 0; j < NI; j++) {
6112                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
6113                 if (DEBUG_SHOW_INFO) {
6114                     Log.v(TAG, "    IntentFilter:");
6115                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6116                 }
6117                 if (!intent.debugCheck()) {
6118                     Log.w(TAG, "==> For Provider " + p.info.name);
6119                 }
6120                 addFilter(intent);
6121             }
6122         }
6123 
removeProvider(PackageParser.Provider p)6124         public final void removeProvider(PackageParser.Provider p) {
6125             mProviders.remove(p.getComponentName());
6126             if (DEBUG_SHOW_INFO) {
6127                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
6128                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
6129                 Log.v(TAG, "    Class=" + p.info.name);
6130             }
6131             final int NI = p.intents.size();
6132             int j;
6133             for (j = 0; j < NI; j++) {
6134                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
6135                 if (DEBUG_SHOW_INFO) {
6136                     Log.v(TAG, "    IntentFilter:");
6137                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
6138                 }
6139                 removeFilter(intent);
6140             }
6141         }
6142 
6143         @Override
allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)6144         protected boolean allowFilterResult(
6145                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
6146             ProviderInfo filterPi = filter.provider.info;
6147             for (int i = dest.size() - 1; i >= 0; i--) {
6148                 ProviderInfo destPi = dest.get(i).providerInfo;
6149                 if (destPi.name == filterPi.name
6150                         && destPi.packageName == filterPi.packageName) {
6151                     return false;
6152                 }
6153             }
6154             return true;
6155         }
6156 
6157         @Override
newArray(int size)6158         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
6159             return new PackageParser.ProviderIntentInfo[size];
6160         }
6161 
6162         @Override
isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)6163         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
6164             if (!sUserManager.exists(userId))
6165                 return true;
6166             PackageParser.Package p = filter.provider.owner;
6167             if (p != null) {
6168                 PackageSetting ps = (PackageSetting) p.mExtras;
6169                 if (ps != null) {
6170                     // System apps are never considered stopped for purposes of
6171                     // filtering, because there may be no way for the user to
6172                     // actually re-launch them.
6173                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
6174                             && ps.getStopped(userId);
6175                 }
6176             }
6177             return false;
6178         }
6179 
6180         @Override
isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)6181         protected boolean isPackageForFilter(String packageName,
6182                 PackageParser.ProviderIntentInfo info) {
6183             return packageName.equals(info.provider.owner.packageName);
6184         }
6185 
6186         @Override
newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)6187         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
6188                 int match, int userId) {
6189             if (!sUserManager.exists(userId))
6190                 return null;
6191             final PackageParser.ProviderIntentInfo info = filter;
6192             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
6193                 return null;
6194             }
6195             final PackageParser.Provider provider = info.provider;
6196             if (mSafeMode && (provider.info.applicationInfo.flags
6197                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
6198                 return null;
6199             }
6200             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
6201             if (ps == null) {
6202                 return null;
6203             }
6204             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
6205                     ps.readUserState(userId), userId);
6206             if (pi == null) {
6207                 return null;
6208             }
6209             final ResolveInfo res = new ResolveInfo();
6210             res.providerInfo = pi;
6211             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
6212                 res.filter = filter;
6213             }
6214             res.priority = info.getPriority();
6215             res.preferredOrder = provider.owner.mPreferredOrder;
6216             res.match = match;
6217             res.isDefault = info.hasDefault;
6218             res.labelRes = info.labelRes;
6219             res.nonLocalizedLabel = info.nonLocalizedLabel;
6220             res.icon = info.icon;
6221             res.system = isSystemApp(res.providerInfo.applicationInfo);
6222             return res;
6223         }
6224 
6225         @Override
sortResults(List<ResolveInfo> results)6226         protected void sortResults(List<ResolveInfo> results) {
6227             Collections.sort(results, mResolvePrioritySorter);
6228         }
6229 
6230         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)6231         protected void dumpFilter(PrintWriter out, String prefix,
6232                 PackageParser.ProviderIntentInfo filter) {
6233             out.print(prefix);
6234             out.print(
6235                     Integer.toHexString(System.identityHashCode(filter.provider)));
6236             out.print(' ');
6237             filter.provider.printComponentShortName(out);
6238             out.print(" filter ");
6239             out.println(Integer.toHexString(System.identityHashCode(filter)));
6240         }
6241 
6242         private final HashMap<ComponentName, PackageParser.Provider> mProviders
6243                 = new HashMap<ComponentName, PackageParser.Provider>();
6244         private int mFlags;
6245     };
6246 
6247     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
6248             new Comparator<ResolveInfo>() {
6249         public int compare(ResolveInfo r1, ResolveInfo r2) {
6250             int v1 = r1.priority;
6251             int v2 = r2.priority;
6252             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
6253             if (v1 != v2) {
6254                 return (v1 > v2) ? -1 : 1;
6255             }
6256             v1 = r1.preferredOrder;
6257             v2 = r2.preferredOrder;
6258             if (v1 != v2) {
6259                 return (v1 > v2) ? -1 : 1;
6260             }
6261             if (r1.isDefault != r2.isDefault) {
6262                 return r1.isDefault ? -1 : 1;
6263             }
6264             v1 = r1.match;
6265             v2 = r2.match;
6266             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
6267             if (v1 != v2) {
6268                 return (v1 > v2) ? -1 : 1;
6269             }
6270             if (r1.system != r2.system) {
6271                 return r1.system ? -1 : 1;
6272             }
6273             return 0;
6274         }
6275     };
6276 
6277     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
6278             new Comparator<ProviderInfo>() {
6279         public int compare(ProviderInfo p1, ProviderInfo p2) {
6280             final int v1 = p1.initOrder;
6281             final int v2 = p2.initOrder;
6282             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
6283         }
6284     };
6285 
sendPackageBroadcast(String action, String pkg, Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, int[] userIds)6286     static final void sendPackageBroadcast(String action, String pkg,
6287             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
6288             int[] userIds) {
6289         IActivityManager am = ActivityManagerNative.getDefault();
6290         if (am != null) {
6291             try {
6292                 if (userIds == null) {
6293                     userIds = am.getRunningUserIds();
6294                 }
6295                 for (int id : userIds) {
6296                     final Intent intent = new Intent(action,
6297                             pkg != null ? Uri.fromParts("package", pkg, null) : null);
6298                     if (extras != null) {
6299                         intent.putExtras(extras);
6300                     }
6301                     if (targetPkg != null) {
6302                         intent.setPackage(targetPkg);
6303                     }
6304                     // Modify the UID when posting to other users
6305                     int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
6306                     if (uid > 0 && UserHandle.getUserId(uid) != id) {
6307                         uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
6308                         intent.putExtra(Intent.EXTRA_UID, uid);
6309                     }
6310                     intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
6311                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
6312                     if (DEBUG_BROADCASTS) {
6313                         RuntimeException here = new RuntimeException("here");
6314                         here.fillInStackTrace();
6315                         Slog.d(TAG, "Sending to user " + id + ": "
6316                                 + intent.toShortString(false, true, false, false)
6317                                 + " " + intent.getExtras(), here);
6318                     }
6319                     am.broadcastIntent(null, intent, null, finishedReceiver,
6320                             0, null, null, null, android.app.AppOpsManager.OP_NONE,
6321                             finishedReceiver != null, false, id);
6322                 }
6323             } catch (RemoteException ex) {
6324             }
6325         }
6326     }
6327 
6328     /**
6329      * Check if the external storage media is available. This is true if there
6330      * is a mounted external storage medium or if the external storage is
6331      * emulated.
6332      */
isExternalMediaAvailable()6333     private boolean isExternalMediaAvailable() {
6334         return mMediaMounted || Environment.isExternalStorageEmulated();
6335     }
6336 
nextPackageToClean(PackageCleanItem lastPackage)6337     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
6338         // writer
6339         synchronized (mPackages) {
6340             if (!isExternalMediaAvailable()) {
6341                 // If the external storage is no longer mounted at this point,
6342                 // the caller may not have been able to delete all of this
6343                 // packages files and can not delete any more.  Bail.
6344                 return null;
6345             }
6346             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
6347             if (lastPackage != null) {
6348                 pkgs.remove(lastPackage);
6349             }
6350             if (pkgs.size() > 0) {
6351                 return pkgs.get(0);
6352             }
6353         }
6354         return null;
6355     }
6356 
schedulePackageCleaning(String packageName, int userId, boolean andCode)6357     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
6358         if (false) {
6359             RuntimeException here = new RuntimeException("here");
6360             here.fillInStackTrace();
6361             Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId
6362                     + " andCode=" + andCode, here);
6363         }
6364         mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE,
6365                 userId, andCode ? 1 : 0, packageName));
6366     }
6367 
startCleaningPackages()6368     void startCleaningPackages() {
6369         // reader
6370         synchronized (mPackages) {
6371             if (!isExternalMediaAvailable()) {
6372                 return;
6373             }
6374             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
6375                 return;
6376             }
6377         }
6378         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
6379         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
6380         IActivityManager am = ActivityManagerNative.getDefault();
6381         if (am != null) {
6382             try {
6383                 am.startService(null, intent, null, UserHandle.USER_OWNER);
6384             } catch (RemoteException e) {
6385             }
6386         }
6387     }
6388 
6389     private final class AppDirObserver extends FileObserver {
AppDirObserver(String path, int mask, boolean isrom, boolean isPrivileged)6390         public AppDirObserver(String path, int mask, boolean isrom, boolean isPrivileged) {
6391             super(path, mask);
6392             mRootDir = path;
6393             mIsRom = isrom;
6394             mIsPrivileged = isPrivileged;
6395         }
6396 
onEvent(int event, String path)6397         public void onEvent(int event, String path) {
6398             String removedPackage = null;
6399             int removedAppId = -1;
6400             int[] removedUsers = null;
6401             String addedPackage = null;
6402             int addedAppId = -1;
6403             int[] addedUsers = null;
6404 
6405             // TODO post a message to the handler to obtain serial ordering
6406             synchronized (mInstallLock) {
6407                 String fullPathStr = null;
6408                 File fullPath = null;
6409                 if (path != null) {
6410                     fullPath = new File(mRootDir, path);
6411                     fullPathStr = fullPath.getPath();
6412                 }
6413 
6414                 if (DEBUG_APP_DIR_OBSERVER)
6415                     Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
6416 
6417                 if (!isPackageFilename(path)) {
6418                     if (DEBUG_APP_DIR_OBSERVER)
6419                         Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
6420                     return;
6421                 }
6422 
6423                 // Ignore packages that are being installed or
6424                 // have just been installed.
6425                 if (ignoreCodePath(fullPathStr)) {
6426                     return;
6427                 }
6428                 PackageParser.Package p = null;
6429                 PackageSetting ps = null;
6430                 // reader
6431                 synchronized (mPackages) {
6432                     p = mAppDirs.get(fullPathStr);
6433                     if (p != null) {
6434                         ps = mSettings.mPackages.get(p.applicationInfo.packageName);
6435                         if (ps != null) {
6436                             removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
6437                         } else {
6438                             removedUsers = sUserManager.getUserIds();
6439                         }
6440                     }
6441                     addedUsers = sUserManager.getUserIds();
6442                 }
6443                 if ((event&REMOVE_EVENTS) != 0) {
6444                     if (ps != null) {
6445                         if (DEBUG_REMOVE) Slog.d(TAG, "Package disappeared: " + ps);
6446                         removePackageLI(ps, true);
6447                         removedPackage = ps.name;
6448                         removedAppId = ps.appId;
6449                     }
6450                 }
6451 
6452                 if ((event&ADD_EVENTS) != 0) {
6453                     if (p == null) {
6454                         if (DEBUG_INSTALL) Slog.d(TAG, "New file appeared: " + fullPath);
6455                         int flags = PackageParser.PARSE_CHATTY | PackageParser.PARSE_MUST_BE_APK;
6456                         if (mIsRom) {
6457                             flags |= PackageParser.PARSE_IS_SYSTEM
6458                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
6459                             if (mIsPrivileged) {
6460                                 flags |= PackageParser.PARSE_IS_PRIVILEGED;
6461                             }
6462                         }
6463                         p = scanPackageLI(fullPath, flags,
6464                                 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
6465                                 System.currentTimeMillis(), UserHandle.ALL);
6466                         if (p != null) {
6467                             /*
6468                              * TODO this seems dangerous as the package may have
6469                              * changed since we last acquired the mPackages
6470                              * lock.
6471                              */
6472                             // writer
6473                             synchronized (mPackages) {
6474                                 updatePermissionsLPw(p.packageName, p,
6475                                         p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
6476                             }
6477                             addedPackage = p.applicationInfo.packageName;
6478                             addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
6479                         }
6480                     }
6481                 }
6482 
6483                 // reader
6484                 synchronized (mPackages) {
6485                     mSettings.writeLPr();
6486                 }
6487             }
6488 
6489             if (removedPackage != null) {
6490                 Bundle extras = new Bundle(1);
6491                 extras.putInt(Intent.EXTRA_UID, removedAppId);
6492                 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
6493                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
6494                         extras, null, null, removedUsers);
6495             }
6496             if (addedPackage != null) {
6497                 Bundle extras = new Bundle(1);
6498                 extras.putInt(Intent.EXTRA_UID, addedAppId);
6499                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
6500                         extras, null, null, addedUsers);
6501             }
6502         }
6503 
6504         private final String mRootDir;
6505         private final boolean mIsRom;
6506         private final boolean mIsPrivileged;
6507     }
6508 
6509     /* Called when a downloaded package installation has been confirmed by the user */
installPackage( final Uri packageURI, final IPackageInstallObserver observer, final int flags)6510     public void installPackage(
6511             final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
6512         installPackage(packageURI, observer, flags, null);
6513     }
6514 
6515     /* Called when a downloaded package installation has been confirmed by the user */
installPackage( final Uri packageURI, final IPackageInstallObserver observer, final int flags, final String installerPackageName)6516     public void installPackage(
6517             final Uri packageURI, final IPackageInstallObserver observer, final int flags,
6518             final String installerPackageName) {
6519         installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
6520                 null, null);
6521     }
6522 
6523     @Override
installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams)6524     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
6525             int flags, String installerPackageName, Uri verificationURI,
6526             ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
6527         VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
6528                 VerificationParams.NO_UID, manifestDigest);
6529         installPackageWithVerificationAndEncryption(packageURI, observer, flags,
6530                 installerPackageName, verificationParams, encryptionParams);
6531     }
6532 
installPackageWithVerificationAndEncryption(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, VerificationParams verificationParams, ContainerEncryptionParams encryptionParams)6533     public void installPackageWithVerificationAndEncryption(Uri packageURI,
6534             IPackageInstallObserver observer, int flags, String installerPackageName,
6535             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
6536         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
6537                 null);
6538 
6539         final int uid = Binder.getCallingUid();
6540         if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
6541             try {
6542                 observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
6543             } catch (RemoteException re) {
6544             }
6545             return;
6546         }
6547 
6548         UserHandle user;
6549         if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
6550             user = UserHandle.ALL;
6551         } else {
6552             user = new UserHandle(UserHandle.getUserId(uid));
6553         }
6554 
6555         final int filteredFlags;
6556 
6557         if (uid == Process.SHELL_UID || uid == 0) {
6558             if (DEBUG_INSTALL) {
6559                 Slog.v(TAG, "Install from ADB");
6560             }
6561             filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
6562         } else {
6563             filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
6564         }
6565 
6566         verificationParams.setInstallerUid(uid);
6567 
6568         final Message msg = mHandler.obtainMessage(INIT_COPY);
6569         msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
6570                 verificationParams, encryptionParams, user);
6571         mHandler.sendMessage(msg);
6572     }
6573 
sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)6574     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
6575         Bundle extras = new Bundle(1);
6576         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
6577 
6578         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
6579                 packageName, extras, null, null, new int[] {userId});
6580         try {
6581             IActivityManager am = ActivityManagerNative.getDefault();
6582             final boolean isSystem =
6583                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
6584             if (isSystem && am.isUserRunning(userId, false)) {
6585                 // The just-installed/enabled app is bundled on the system, so presumed
6586                 // to be able to run automatically without needing an explicit launch.
6587                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
6588                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
6589                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
6590                         .setPackage(packageName);
6591                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
6592                         android.app.AppOpsManager.OP_NONE, false, false, userId);
6593             }
6594         } catch (RemoteException e) {
6595             // shouldn't happen
6596             Slog.w(TAG, "Unable to bootstrap installed package", e);
6597         }
6598     }
6599 
6600     @Override
setApplicationBlockedSettingAsUser(String packageName, boolean blocked, int userId)6601     public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
6602             int userId) {
6603         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
6604         PackageSetting pkgSetting;
6605         final int uid = Binder.getCallingUid();
6606         if (UserHandle.getUserId(uid) != userId) {
6607             mContext.enforceCallingOrSelfPermission(
6608                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6609                     "setApplicationBlockedSetting for user " + userId);
6610         }
6611 
6612         if (blocked && isPackageDeviceAdmin(packageName, userId)) {
6613             Slog.w(TAG, "Not blocking package " + packageName + ": has active device admin");
6614             return false;
6615         }
6616 
6617         long callingId = Binder.clearCallingIdentity();
6618         try {
6619             boolean sendAdded = false;
6620             boolean sendRemoved = false;
6621             // writer
6622             synchronized (mPackages) {
6623                 pkgSetting = mSettings.mPackages.get(packageName);
6624                 if (pkgSetting == null) {
6625                     return false;
6626                 }
6627                 if (pkgSetting.getBlocked(userId) != blocked) {
6628                     pkgSetting.setBlocked(blocked, userId);
6629                     mSettings.writePackageRestrictionsLPr(userId);
6630                     if (blocked) {
6631                         sendRemoved = true;
6632                     } else {
6633                         sendAdded = true;
6634                     }
6635                 }
6636             }
6637             if (sendAdded) {
6638                 sendPackageAddedForUser(packageName, pkgSetting, userId);
6639                 return true;
6640             }
6641             if (sendRemoved) {
6642                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
6643                         "blocking pkg");
6644                 sendPackageBlockedForUser(packageName, pkgSetting, userId);
6645             }
6646         } finally {
6647             Binder.restoreCallingIdentity(callingId);
6648         }
6649         return false;
6650     }
6651 
sendPackageBlockedForUser(String packageName, PackageSetting pkgSetting, int userId)6652     private void sendPackageBlockedForUser(String packageName, PackageSetting pkgSetting,
6653             int userId) {
6654         final PackageRemovedInfo info = new PackageRemovedInfo();
6655         info.removedPackage = packageName;
6656         info.removedUsers = new int[] {userId};
6657         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
6658         info.sendBroadcast(false, false, false);
6659     }
6660 
6661     /**
6662      * Returns true if application is not found or there was an error. Otherwise it returns
6663      * the blocked state of the package for the given user.
6664      */
6665     @Override
getApplicationBlockedSettingAsUser(String packageName, int userId)6666     public boolean getApplicationBlockedSettingAsUser(String packageName, int userId) {
6667         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
6668         PackageSetting pkgSetting;
6669         final int uid = Binder.getCallingUid();
6670         if (UserHandle.getUserId(uid) != userId) {
6671             mContext.enforceCallingPermission(
6672                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6673                     "getApplicationBlocked for user " + userId);
6674         }
6675         long callingId = Binder.clearCallingIdentity();
6676         try {
6677             // writer
6678             synchronized (mPackages) {
6679                 pkgSetting = mSettings.mPackages.get(packageName);
6680                 if (pkgSetting == null) {
6681                     return true;
6682                 }
6683                 return pkgSetting.getBlocked(userId);
6684             }
6685         } finally {
6686             Binder.restoreCallingIdentity(callingId);
6687         }
6688     }
6689 
6690     /**
6691      * @hide
6692      */
6693     @Override
installExistingPackageAsUser(String packageName, int userId)6694     public int installExistingPackageAsUser(String packageName, int userId) {
6695         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
6696                 null);
6697         PackageSetting pkgSetting;
6698         final int uid = Binder.getCallingUid();
6699         if (UserHandle.getUserId(uid) != userId) {
6700             mContext.enforceCallingPermission(
6701                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6702                     "installExistingPackage for user " + userId);
6703         }
6704         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
6705             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
6706         }
6707 
6708         long callingId = Binder.clearCallingIdentity();
6709         try {
6710             boolean sendAdded = false;
6711             Bundle extras = new Bundle(1);
6712 
6713             // writer
6714             synchronized (mPackages) {
6715                 pkgSetting = mSettings.mPackages.get(packageName);
6716                 if (pkgSetting == null) {
6717                     return PackageManager.INSTALL_FAILED_INVALID_URI;
6718                 }
6719                 if (!pkgSetting.getInstalled(userId)) {
6720                     pkgSetting.setInstalled(true, userId);
6721                     pkgSetting.setBlocked(false, userId);
6722                     mSettings.writePackageRestrictionsLPr(userId);
6723                     sendAdded = true;
6724                 }
6725             }
6726 
6727             if (sendAdded) {
6728                 sendPackageAddedForUser(packageName, pkgSetting, userId);
6729             }
6730         } finally {
6731             Binder.restoreCallingIdentity(callingId);
6732         }
6733 
6734         return PackageManager.INSTALL_SUCCEEDED;
6735     }
6736 
isUserRestricted(int userId, String restrictionKey)6737     private boolean isUserRestricted(int userId, String restrictionKey) {
6738         Bundle restrictions = sUserManager.getUserRestrictions(userId);
6739         if (restrictions.getBoolean(restrictionKey, false)) {
6740             Log.w(TAG, "User is restricted: " + restrictionKey);
6741             return true;
6742         }
6743         return false;
6744     }
6745 
6746     @Override
verifyPendingInstall(int id, int verificationCode)6747     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
6748         mContext.enforceCallingOrSelfPermission(
6749                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
6750                 "Only package verification agents can verify applications");
6751 
6752         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
6753         final PackageVerificationResponse response = new PackageVerificationResponse(
6754                 verificationCode, Binder.getCallingUid());
6755         msg.arg1 = id;
6756         msg.obj = response;
6757         mHandler.sendMessage(msg);
6758     }
6759 
6760     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)6761     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
6762             long millisecondsToDelay) {
6763         mContext.enforceCallingOrSelfPermission(
6764                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
6765                 "Only package verification agents can extend verification timeouts");
6766 
6767         final PackageVerificationState state = mPendingVerification.get(id);
6768         final PackageVerificationResponse response = new PackageVerificationResponse(
6769                 verificationCodeAtTimeout, Binder.getCallingUid());
6770 
6771         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
6772             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
6773         }
6774         if (millisecondsToDelay < 0) {
6775             millisecondsToDelay = 0;
6776         }
6777         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
6778                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
6779             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
6780         }
6781 
6782         if ((state != null) && !state.timeoutExtended()) {
6783             state.extendTimeout();
6784 
6785             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
6786             msg.arg1 = id;
6787             msg.obj = response;
6788             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
6789         }
6790     }
6791 
broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)6792     private void broadcastPackageVerified(int verificationId, Uri packageUri,
6793             int verificationCode, UserHandle user) {
6794         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
6795         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
6796         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
6797         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
6798         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
6799 
6800         mContext.sendBroadcastAsUser(intent, user,
6801                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
6802     }
6803 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)6804     private ComponentName matchComponentForVerifier(String packageName,
6805             List<ResolveInfo> receivers) {
6806         ActivityInfo targetReceiver = null;
6807 
6808         final int NR = receivers.size();
6809         for (int i = 0; i < NR; i++) {
6810             final ResolveInfo info = receivers.get(i);
6811             if (info.activityInfo == null) {
6812                 continue;
6813             }
6814 
6815             if (packageName.equals(info.activityInfo.packageName)) {
6816                 targetReceiver = info.activityInfo;
6817                 break;
6818             }
6819         }
6820 
6821         if (targetReceiver == null) {
6822             return null;
6823         }
6824 
6825         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
6826     }
6827 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)6828     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
6829             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
6830         if (pkgInfo.verifiers.length == 0) {
6831             return null;
6832         }
6833 
6834         final int N = pkgInfo.verifiers.length;
6835         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
6836         for (int i = 0; i < N; i++) {
6837             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
6838 
6839             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
6840                     receivers);
6841             if (comp == null) {
6842                 continue;
6843             }
6844 
6845             final int verifierUid = getUidForVerifier(verifierInfo);
6846             if (verifierUid == -1) {
6847                 continue;
6848             }
6849 
6850             if (DEBUG_VERIFY) {
6851                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
6852                         + " with the correct signature");
6853             }
6854             sufficientVerifiers.add(comp);
6855             verificationState.addSufficientVerifier(verifierUid);
6856         }
6857 
6858         return sufficientVerifiers;
6859     }
6860 
getUidForVerifier(VerifierInfo verifierInfo)6861     private int getUidForVerifier(VerifierInfo verifierInfo) {
6862         synchronized (mPackages) {
6863             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
6864             if (pkg == null) {
6865                 return -1;
6866             } else if (pkg.mSignatures.length != 1) {
6867                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
6868                         + " has more than one signature; ignoring");
6869                 return -1;
6870             }
6871 
6872             /*
6873              * If the public key of the package's signature does not match
6874              * our expected public key, then this is a different package and
6875              * we should skip.
6876              */
6877 
6878             final byte[] expectedPublicKey;
6879             try {
6880                 final Signature verifierSig = pkg.mSignatures[0];
6881                 final PublicKey publicKey = verifierSig.getPublicKey();
6882                 expectedPublicKey = publicKey.getEncoded();
6883             } catch (CertificateException e) {
6884                 return -1;
6885             }
6886 
6887             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
6888 
6889             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
6890                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
6891                         + " does not have the expected public key; ignoring");
6892                 return -1;
6893             }
6894 
6895             return pkg.applicationInfo.uid;
6896         }
6897     }
6898 
finishPackageInstall(int token)6899     public void finishPackageInstall(int token) {
6900         enforceSystemOrRoot("Only the system is allowed to finish installs");
6901 
6902         if (DEBUG_INSTALL) {
6903             Slog.v(TAG, "BM finishing package install for " + token);
6904         }
6905 
6906         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
6907         mHandler.sendMessage(msg);
6908     }
6909 
6910     /**
6911      * Get the verification agent timeout.
6912      *
6913      * @return verification timeout in milliseconds
6914      */
getVerificationTimeout()6915     private long getVerificationTimeout() {
6916         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
6917                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
6918                 DEFAULT_VERIFICATION_TIMEOUT);
6919     }
6920 
6921     /**
6922      * Get the default verification agent response code.
6923      *
6924      * @return default verification response code
6925      */
getDefaultVerificationResponse()6926     private int getDefaultVerificationResponse() {
6927         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6928                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
6929                 DEFAULT_VERIFICATION_RESPONSE);
6930     }
6931 
6932     /**
6933      * Check whether or not package verification has been enabled.
6934      *
6935      * @return true if verification should be performed
6936      */
isVerificationEnabled(int flags)6937     private boolean isVerificationEnabled(int flags) {
6938         if (!DEFAULT_VERIFY_ENABLE) {
6939             return false;
6940         }
6941 
6942         // Check if installing from ADB
6943         if ((flags & PackageManager.INSTALL_FROM_ADB) != 0) {
6944             // Do not run verification in a test harness environment
6945             if (ActivityManager.isRunningInTestHarness()) {
6946                 return false;
6947             }
6948             // Check if the developer does not want package verification for ADB installs
6949             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6950                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
6951                 return false;
6952             }
6953         }
6954 
6955         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6956                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
6957     }
6958 
6959     /**
6960      * Get the "allow unknown sources" setting.
6961      *
6962      * @return the current "allow unknown sources" setting
6963      */
getUnknownSourcesSettings()6964     private int getUnknownSourcesSettings() {
6965         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6966                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
6967                 -1);
6968     }
6969 
setInstallerPackageName(String targetPackage, String installerPackageName)6970     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
6971         final int uid = Binder.getCallingUid();
6972         // writer
6973         synchronized (mPackages) {
6974             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
6975             if (targetPackageSetting == null) {
6976                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
6977             }
6978 
6979             PackageSetting installerPackageSetting;
6980             if (installerPackageName != null) {
6981                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
6982                 if (installerPackageSetting == null) {
6983                     throw new IllegalArgumentException("Unknown installer package: "
6984                             + installerPackageName);
6985                 }
6986             } else {
6987                 installerPackageSetting = null;
6988             }
6989 
6990             Signature[] callerSignature;
6991             Object obj = mSettings.getUserIdLPr(uid);
6992             if (obj != null) {
6993                 if (obj instanceof SharedUserSetting) {
6994                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
6995                 } else if (obj instanceof PackageSetting) {
6996                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
6997                 } else {
6998                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
6999                 }
7000             } else {
7001                 throw new SecurityException("Unknown calling uid " + uid);
7002             }
7003 
7004             // Verify: can't set installerPackageName to a package that is
7005             // not signed with the same cert as the caller.
7006             if (installerPackageSetting != null) {
7007                 if (compareSignatures(callerSignature,
7008                         installerPackageSetting.signatures.mSignatures)
7009                         != PackageManager.SIGNATURE_MATCH) {
7010                     throw new SecurityException(
7011                             "Caller does not have same cert as new installer package "
7012                             + installerPackageName);
7013                 }
7014             }
7015 
7016             // Verify: if target already has an installer package, it must
7017             // be signed with the same cert as the caller.
7018             if (targetPackageSetting.installerPackageName != null) {
7019                 PackageSetting setting = mSettings.mPackages.get(
7020                         targetPackageSetting.installerPackageName);
7021                 // If the currently set package isn't valid, then it's always
7022                 // okay to change it.
7023                 if (setting != null) {
7024                     if (compareSignatures(callerSignature,
7025                             setting.signatures.mSignatures)
7026                             != PackageManager.SIGNATURE_MATCH) {
7027                         throw new SecurityException(
7028                                 "Caller does not have same cert as old installer package "
7029                                 + targetPackageSetting.installerPackageName);
7030                     }
7031                 }
7032             }
7033 
7034             // Okay!
7035             targetPackageSetting.installerPackageName = installerPackageName;
7036             scheduleWriteSettingsLocked();
7037         }
7038     }
7039 
processPendingInstall(final InstallArgs args, final int currentStatus)7040     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
7041         // Queue up an async operation since the package installation may take a little while.
7042         mHandler.post(new Runnable() {
7043             public void run() {
7044                 mHandler.removeCallbacks(this);
7045                  // Result object to be returned
7046                 PackageInstalledInfo res = new PackageInstalledInfo();
7047                 res.returnCode = currentStatus;
7048                 res.uid = -1;
7049                 res.pkg = null;
7050                 res.removedInfo = new PackageRemovedInfo();
7051                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
7052                     args.doPreInstall(res.returnCode);
7053                     synchronized (mInstallLock) {
7054                         installPackageLI(args, true, res);
7055                     }
7056                     args.doPostInstall(res.returnCode, res.uid);
7057                 }
7058 
7059                 // A restore should be performed at this point if (a) the install
7060                 // succeeded, (b) the operation is not an update, and (c) the new
7061                 // package has a backupAgent defined.
7062                 final boolean update = res.removedInfo.removedPackage != null;
7063                 boolean doRestore = (!update
7064                         && res.pkg != null
7065                         && res.pkg.applicationInfo.backupAgentName != null);
7066 
7067                 // Set up the post-install work request bookkeeping.  This will be used
7068                 // and cleaned up by the post-install event handling regardless of whether
7069                 // there's a restore pass performed.  Token values are >= 1.
7070                 int token;
7071                 if (mNextInstallToken < 0) mNextInstallToken = 1;
7072                 token = mNextInstallToken++;
7073 
7074                 PostInstallData data = new PostInstallData(args, res);
7075                 mRunningInstalls.put(token, data);
7076                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
7077 
7078                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
7079                     // Pass responsibility to the Backup Manager.  It will perform a
7080                     // restore if appropriate, then pass responsibility back to the
7081                     // Package Manager to run the post-install observer callbacks
7082                     // and broadcasts.
7083                     IBackupManager bm = IBackupManager.Stub.asInterface(
7084                             ServiceManager.getService(Context.BACKUP_SERVICE));
7085                     if (bm != null) {
7086                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
7087                                 + " to BM for possible restore");
7088                         try {
7089                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
7090                         } catch (RemoteException e) {
7091                             // can't happen; the backup manager is local
7092                         } catch (Exception e) {
7093                             Slog.e(TAG, "Exception trying to enqueue restore", e);
7094                             doRestore = false;
7095                         }
7096                     } else {
7097                         Slog.e(TAG, "Backup Manager not found!");
7098                         doRestore = false;
7099                     }
7100                 }
7101 
7102                 if (!doRestore) {
7103                     // No restore possible, or the Backup Manager was mysteriously not
7104                     // available -- just fire the post-install work request directly.
7105                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
7106                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
7107                     mHandler.sendMessage(msg);
7108                 }
7109             }
7110         });
7111     }
7112 
7113     private abstract class HandlerParams {
7114         private static final int MAX_RETRIES = 4;
7115 
7116         /**
7117          * Number of times startCopy() has been attempted and had a non-fatal
7118          * error.
7119          */
7120         private int mRetries = 0;
7121 
7122         /** User handle for the user requesting the information or installation. */
7123         private final UserHandle mUser;
7124 
HandlerParams(UserHandle user)7125         HandlerParams(UserHandle user) {
7126             mUser = user;
7127         }
7128 
getUser()7129         UserHandle getUser() {
7130             return mUser;
7131         }
7132 
startCopy()7133         final boolean startCopy() {
7134             boolean res;
7135             try {
7136                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
7137 
7138                 if (++mRetries > MAX_RETRIES) {
7139                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
7140                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
7141                     handleServiceError();
7142                     return false;
7143                 } else {
7144                     handleStartCopy();
7145                     res = true;
7146                 }
7147             } catch (RemoteException e) {
7148                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
7149                 mHandler.sendEmptyMessage(MCS_RECONNECT);
7150                 res = false;
7151             }
7152             handleReturnCode();
7153             return res;
7154         }
7155 
serviceError()7156         final void serviceError() {
7157             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
7158             handleServiceError();
7159             handleReturnCode();
7160         }
7161 
handleStartCopy()7162         abstract void handleStartCopy() throws RemoteException;
handleServiceError()7163         abstract void handleServiceError();
handleReturnCode()7164         abstract void handleReturnCode();
7165     }
7166 
7167     class MeasureParams extends HandlerParams {
7168         private final PackageStats mStats;
7169         private boolean mSuccess;
7170 
7171         private final IPackageStatsObserver mObserver;
7172 
MeasureParams(PackageStats stats, IPackageStatsObserver observer)7173         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
7174             super(new UserHandle(stats.userHandle));
7175             mObserver = observer;
7176             mStats = stats;
7177         }
7178 
7179         @Override
toString()7180         public String toString() {
7181             return "MeasureParams{"
7182                 + Integer.toHexString(System.identityHashCode(this))
7183                 + " " + mStats.packageName + "}";
7184         }
7185 
7186         @Override
handleStartCopy()7187         void handleStartCopy() throws RemoteException {
7188             synchronized (mInstallLock) {
7189                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
7190             }
7191 
7192             final boolean mounted;
7193             if (Environment.isExternalStorageEmulated()) {
7194                 mounted = true;
7195             } else {
7196                 final String status = Environment.getExternalStorageState();
7197                 mounted = (Environment.MEDIA_MOUNTED.equals(status)
7198                         || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
7199             }
7200 
7201             if (mounted) {
7202                 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
7203 
7204                 mStats.externalCacheSize = calculateDirectorySize(mContainerService,
7205                         userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
7206 
7207                 mStats.externalDataSize = calculateDirectorySize(mContainerService,
7208                         userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
7209 
7210                 // Always subtract cache size, since it's a subdirectory
7211                 mStats.externalDataSize -= mStats.externalCacheSize;
7212 
7213                 mStats.externalMediaSize = calculateDirectorySize(mContainerService,
7214                         userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
7215 
7216                 mStats.externalObbSize = calculateDirectorySize(mContainerService,
7217                         userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
7218             }
7219         }
7220 
7221         @Override
handleReturnCode()7222         void handleReturnCode() {
7223             if (mObserver != null) {
7224                 try {
7225                     mObserver.onGetStatsCompleted(mStats, mSuccess);
7226                 } catch (RemoteException e) {
7227                     Slog.i(TAG, "Observer no longer exists.");
7228                 }
7229             }
7230         }
7231 
7232         @Override
handleServiceError()7233         void handleServiceError() {
7234             Slog.e(TAG, "Could not measure application " + mStats.packageName
7235                             + " external storage");
7236         }
7237     }
7238 
calculateDirectorySize(IMediaContainerService mcs, File[] paths)7239     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
7240             throws RemoteException {
7241         long result = 0;
7242         for (File path : paths) {
7243             result += mcs.calculateDirectorySize(path.getAbsolutePath());
7244         }
7245         return result;
7246     }
7247 
clearDirectory(IMediaContainerService mcs, File[] paths)7248     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
7249         for (File path : paths) {
7250             try {
7251                 mcs.clearDirectory(path.getAbsolutePath());
7252             } catch (RemoteException e) {
7253             }
7254         }
7255     }
7256 
7257     class InstallParams extends HandlerParams {
7258         final IPackageInstallObserver observer;
7259         int flags;
7260 
7261         private final Uri mPackageURI;
7262         final String installerPackageName;
7263         final VerificationParams verificationParams;
7264         private InstallArgs mArgs;
7265         private int mRet;
7266         private File mTempPackage;
7267         final ContainerEncryptionParams encryptionParams;
7268 
InstallParams(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, VerificationParams verificationParams, ContainerEncryptionParams encryptionParams, UserHandle user)7269         InstallParams(Uri packageURI,
7270                 IPackageInstallObserver observer, int flags,
7271                 String installerPackageName, VerificationParams verificationParams,
7272                 ContainerEncryptionParams encryptionParams, UserHandle user) {
7273             super(user);
7274             this.mPackageURI = packageURI;
7275             this.flags = flags;
7276             this.observer = observer;
7277             this.installerPackageName = installerPackageName;
7278             this.verificationParams = verificationParams;
7279             this.encryptionParams = encryptionParams;
7280         }
7281 
7282         @Override
toString()7283         public String toString() {
7284             return "InstallParams{"
7285                 + Integer.toHexString(System.identityHashCode(this))
7286                 + " " + mPackageURI + "}";
7287         }
7288 
getManifestDigest()7289         public ManifestDigest getManifestDigest() {
7290             if (verificationParams == null) {
7291                 return null;
7292             }
7293             return verificationParams.getManifestDigest();
7294         }
7295 
installLocationPolicy(PackageInfoLite pkgLite, int flags)7296         private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
7297             String packageName = pkgLite.packageName;
7298             int installLocation = pkgLite.installLocation;
7299             boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
7300             // reader
7301             synchronized (mPackages) {
7302                 PackageParser.Package pkg = mPackages.get(packageName);
7303                 if (pkg != null) {
7304                     if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
7305                         // Check for downgrading.
7306                         if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
7307                             if (pkgLite.versionCode < pkg.mVersionCode) {
7308                                 Slog.w(TAG, "Can't install update of " + packageName
7309                                         + " update version " + pkgLite.versionCode
7310                                         + " is older than installed version "
7311                                         + pkg.mVersionCode);
7312                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
7313                             }
7314                         }
7315                         // Check for updated system application.
7316                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7317                             if (onSd) {
7318                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
7319                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
7320                             }
7321                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
7322                         } else {
7323                             if (onSd) {
7324                                 // Install flag overrides everything.
7325                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
7326                             }
7327                             // If current upgrade specifies particular preference
7328                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
7329                                 // Application explicitly specified internal.
7330                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
7331                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
7332                                 // App explictly prefers external. Let policy decide
7333                             } else {
7334                                 // Prefer previous location
7335                                 if (isExternal(pkg)) {
7336                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
7337                                 }
7338                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
7339                             }
7340                         }
7341                     } else {
7342                         // Invalid install. Return error code
7343                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
7344                     }
7345                 }
7346             }
7347             // All the special cases have been taken care of.
7348             // Return result based on recommended install location.
7349             if (onSd) {
7350                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
7351             }
7352             return pkgLite.recommendedInstallLocation;
7353         }
7354 
7355         /*
7356          * Invoke remote method to get package information and install
7357          * location values. Override install location based on default
7358          * policy if needed and then create install arguments based
7359          * on the install location.
7360          */
handleStartCopy()7361         public void handleStartCopy() throws RemoteException {
7362             int ret = PackageManager.INSTALL_SUCCEEDED;
7363             final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
7364             final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
7365             PackageInfoLite pkgLite = null;
7366 
7367             if (onInt && onSd) {
7368                 // Check if both bits are set.
7369                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
7370                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
7371             } else {
7372                 final long lowThreshold;
7373 
7374                 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
7375                         .getService(DeviceStorageMonitorService.SERVICE);
7376                 if (dsm == null) {
7377                     Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
7378                     lowThreshold = 0L;
7379                 } else {
7380                     lowThreshold = dsm.getMemoryLowThreshold();
7381                 }
7382 
7383                 try {
7384                     mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI,
7385                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
7386 
7387                     final File packageFile;
7388                     if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) {
7389                         mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir);
7390                         if (mTempPackage != null) {
7391                             ParcelFileDescriptor out;
7392                             try {
7393                                 out = ParcelFileDescriptor.open(mTempPackage,
7394                                         ParcelFileDescriptor.MODE_READ_WRITE);
7395                             } catch (FileNotFoundException e) {
7396                                 out = null;
7397                                 Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI);
7398                             }
7399 
7400                             // Make a temporary file for decryption.
7401                             ret = mContainerService
7402                                     .copyResource(mPackageURI, encryptionParams, out);
7403                             IoUtils.closeQuietly(out);
7404 
7405                             packageFile = mTempPackage;
7406 
7407                             FileUtils.setPermissions(packageFile.getAbsolutePath(),
7408                                     FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP
7409                                             | FileUtils.S_IROTH,
7410                                     -1, -1);
7411                         } else {
7412                             packageFile = null;
7413                         }
7414                     } else {
7415                         packageFile = new File(mPackageURI.getPath());
7416                     }
7417 
7418                     if (packageFile != null) {
7419                         // Remote call to find out default install location
7420                         final String packageFilePath = packageFile.getAbsolutePath();
7421                         pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags,
7422                                 lowThreshold);
7423 
7424                         /*
7425                          * If we have too little free space, try to free cache
7426                          * before giving up.
7427                          */
7428                         if (pkgLite.recommendedInstallLocation
7429                                 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
7430                             final long size = mContainerService.calculateInstalledSize(
7431                                     packageFilePath, isForwardLocked());
7432                             if (mInstaller.freeCache(size + lowThreshold) >= 0) {
7433                                 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath,
7434                                         flags, lowThreshold);
7435                             }
7436                             /*
7437                              * The cache free must have deleted the file we
7438                              * downloaded to install.
7439                              *
7440                              * TODO: fix the "freeCache" call to not delete
7441                              *       the file we care about.
7442                              */
7443                             if (pkgLite.recommendedInstallLocation
7444                                     == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
7445                                 pkgLite.recommendedInstallLocation
7446                                     = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
7447                             }
7448                         }
7449                     }
7450                 } finally {
7451                     mContext.revokeUriPermission(mPackageURI,
7452                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
7453                 }
7454             }
7455 
7456             if (ret == PackageManager.INSTALL_SUCCEEDED) {
7457                 int loc = pkgLite.recommendedInstallLocation;
7458                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
7459                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
7460                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
7461                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
7462                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
7463                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7464                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
7465                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
7466                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
7467                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
7468                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
7469                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
7470                 } else {
7471                     // Override with defaults if needed.
7472                     loc = installLocationPolicy(pkgLite, flags);
7473                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
7474                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
7475                     } else if (!onSd && !onInt) {
7476                         // Override install location with flags
7477                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
7478                             // Set the flag to install on external media.
7479                             flags |= PackageManager.INSTALL_EXTERNAL;
7480                             flags &= ~PackageManager.INSTALL_INTERNAL;
7481                         } else {
7482                             // Make sure the flag for installing on external
7483                             // media is unset
7484                             flags |= PackageManager.INSTALL_INTERNAL;
7485                             flags &= ~PackageManager.INSTALL_EXTERNAL;
7486                         }
7487                     }
7488                 }
7489             }
7490 
7491             final InstallArgs args = createInstallArgs(this);
7492             mArgs = args;
7493 
7494             if (ret == PackageManager.INSTALL_SUCCEEDED) {
7495                  /*
7496                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
7497                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
7498                  */
7499                 int userIdentifier = getUser().getIdentifier();
7500                 if (userIdentifier == UserHandle.USER_ALL
7501                         && ((flags & PackageManager.INSTALL_FROM_ADB) != 0)) {
7502                     userIdentifier = UserHandle.USER_OWNER;
7503                 }
7504 
7505                 /*
7506                  * Determine if we have any installed package verifiers. If we
7507                  * do, then we'll defer to them to verify the packages.
7508                  */
7509                 final int requiredUid = mRequiredVerifierPackage == null ? -1
7510                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
7511                 if (requiredUid != -1 && isVerificationEnabled(flags)) {
7512                     final Intent verification = new Intent(
7513                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
7514                     verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE);
7515                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
7516 
7517                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
7518                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
7519                             0 /* TODO: Which userId? */);
7520 
7521                     if (DEBUG_VERIFY) {
7522                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
7523                                 + verification.toString() + " with " + pkgLite.verifiers.length
7524                                 + " optional verifiers");
7525                     }
7526 
7527                     final int verificationId = mPendingVerificationToken++;
7528 
7529                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
7530 
7531                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
7532                             installerPackageName);
7533 
7534                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
7535 
7536                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
7537                             pkgLite.packageName);
7538 
7539                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
7540                             pkgLite.versionCode);
7541 
7542                     if (verificationParams != null) {
7543                         if (verificationParams.getVerificationURI() != null) {
7544                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
7545                                  verificationParams.getVerificationURI());
7546                         }
7547                         if (verificationParams.getOriginatingURI() != null) {
7548                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
7549                                   verificationParams.getOriginatingURI());
7550                         }
7551                         if (verificationParams.getReferrer() != null) {
7552                             verification.putExtra(Intent.EXTRA_REFERRER,
7553                                   verificationParams.getReferrer());
7554                         }
7555                         if (verificationParams.getOriginatingUid() >= 0) {
7556                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
7557                                   verificationParams.getOriginatingUid());
7558                         }
7559                         if (verificationParams.getInstallerUid() >= 0) {
7560                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
7561                                   verificationParams.getInstallerUid());
7562                         }
7563                     }
7564 
7565                     final PackageVerificationState verificationState = new PackageVerificationState(
7566                             requiredUid, args);
7567 
7568                     mPendingVerification.append(verificationId, verificationState);
7569 
7570                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
7571                             receivers, verificationState);
7572 
7573                     /*
7574                      * If any sufficient verifiers were listed in the package
7575                      * manifest, attempt to ask them.
7576                      */
7577                     if (sufficientVerifiers != null) {
7578                         final int N = sufficientVerifiers.size();
7579                         if (N == 0) {
7580                             Slog.i(TAG, "Additional verifiers required, but none installed.");
7581                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
7582                         } else {
7583                             for (int i = 0; i < N; i++) {
7584                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
7585 
7586                                 final Intent sufficientIntent = new Intent(verification);
7587                                 sufficientIntent.setComponent(verifierComponent);
7588 
7589                                 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
7590                             }
7591                         }
7592                     }
7593 
7594                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
7595                             mRequiredVerifierPackage, receivers);
7596                     if (ret == PackageManager.INSTALL_SUCCEEDED
7597                             && mRequiredVerifierPackage != null) {
7598                         /*
7599                          * Send the intent to the required verification agent,
7600                          * but only start the verification timeout after the
7601                          * target BroadcastReceivers have run.
7602                          */
7603                         verification.setComponent(requiredVerifierComponent);
7604                         mContext.sendOrderedBroadcastAsUser(verification, getUser(),
7605                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
7606                                 new BroadcastReceiver() {
7607                                     @Override
7608                                     public void onReceive(Context context, Intent intent) {
7609                                         final Message msg = mHandler
7610                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
7611                                         msg.arg1 = verificationId;
7612                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
7613                                     }
7614                                 }, null, 0, null, null);
7615 
7616                         /*
7617                          * We don't want the copy to proceed until verification
7618                          * succeeds, so null out this field.
7619                          */
7620                         mArgs = null;
7621                     }
7622                 } else {
7623                     /*
7624                      * No package verification is enabled, so immediately start
7625                      * the remote call to initiate copy using temporary file.
7626                      */
7627                     ret = args.copyApk(mContainerService, true);
7628                 }
7629             }
7630 
7631             mRet = ret;
7632         }
7633 
7634         @Override
handleReturnCode()7635         void handleReturnCode() {
7636             // If mArgs is null, then MCS couldn't be reached. When it
7637             // reconnects, it will try again to install. At that point, this
7638             // will succeed.
7639             if (mArgs != null) {
7640                 processPendingInstall(mArgs, mRet);
7641 
7642                 if (mTempPackage != null) {
7643                     if (!mTempPackage.delete()) {
7644                         Slog.w(TAG, "Couldn't delete temporary file: " +
7645                                 mTempPackage.getAbsolutePath());
7646                     }
7647                 }
7648             }
7649         }
7650 
7651         @Override
handleServiceError()7652         void handleServiceError() {
7653             mArgs = createInstallArgs(this);
7654             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7655         }
7656 
isForwardLocked()7657         public boolean isForwardLocked() {
7658             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7659         }
7660 
getPackageUri()7661         public Uri getPackageUri() {
7662             if (mTempPackage != null) {
7663                 return Uri.fromFile(mTempPackage);
7664             } else {
7665                 return mPackageURI;
7666             }
7667         }
7668     }
7669 
7670     /*
7671      * Utility class used in movePackage api.
7672      * srcArgs and targetArgs are not set for invalid flags and make
7673      * sure to do null checks when invoking methods on them.
7674      * We probably want to return ErrorPrams for both failed installs
7675      * and moves.
7676      */
7677     class MoveParams extends HandlerParams {
7678         final IPackageMoveObserver observer;
7679         final int flags;
7680         final String packageName;
7681         final InstallArgs srcArgs;
7682         final InstallArgs targetArgs;
7683         int uid;
7684         int mRet;
7685 
MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, String packageName, String dataDir, int uid, UserHandle user)7686         MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
7687                 String packageName, String dataDir, int uid, UserHandle user) {
7688             super(user);
7689             this.srcArgs = srcArgs;
7690             this.observer = observer;
7691             this.flags = flags;
7692             this.packageName = packageName;
7693             this.uid = uid;
7694             if (srcArgs != null) {
7695                 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
7696                 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
7697             } else {
7698                 targetArgs = null;
7699             }
7700         }
7701 
7702         @Override
toString()7703         public String toString() {
7704             return "MoveParams{"
7705                 + Integer.toHexString(System.identityHashCode(this))
7706                 + " " + packageName + "}";
7707         }
7708 
handleStartCopy()7709         public void handleStartCopy() throws RemoteException {
7710             mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7711             // Check for storage space on target medium
7712             if (!targetArgs.checkFreeStorage(mContainerService)) {
7713                 Log.w(TAG, "Insufficient storage to install");
7714                 return;
7715             }
7716 
7717             mRet = srcArgs.doPreCopy();
7718             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7719                 return;
7720             }
7721 
7722             mRet = targetArgs.copyApk(mContainerService, false);
7723             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7724                 srcArgs.doPostCopy(uid);
7725                 return;
7726             }
7727 
7728             mRet = srcArgs.doPostCopy(uid);
7729             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7730                 return;
7731             }
7732 
7733             mRet = targetArgs.doPreInstall(mRet);
7734             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7735                 return;
7736             }
7737 
7738             if (DEBUG_SD_INSTALL) {
7739                 StringBuilder builder = new StringBuilder();
7740                 if (srcArgs != null) {
7741                     builder.append("src: ");
7742                     builder.append(srcArgs.getCodePath());
7743                 }
7744                 if (targetArgs != null) {
7745                     builder.append(" target : ");
7746                     builder.append(targetArgs.getCodePath());
7747                 }
7748                 Log.i(TAG, builder.toString());
7749             }
7750         }
7751 
7752         @Override
handleReturnCode()7753         void handleReturnCode() {
7754             targetArgs.doPostInstall(mRet, uid);
7755             int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
7756             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
7757                 currentStatus = PackageManager.MOVE_SUCCEEDED;
7758             } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
7759                 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
7760             }
7761             processPendingMove(this, currentStatus);
7762         }
7763 
7764         @Override
handleServiceError()7765         void handleServiceError() {
7766             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7767         }
7768     }
7769 
7770     /**
7771      * Used during creation of InstallArgs
7772      *
7773      * @param flags package installation flags
7774      * @return true if should be installed on external storage
7775      */
installOnSd(int flags)7776     private static boolean installOnSd(int flags) {
7777         if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
7778             return false;
7779         }
7780         if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
7781             return true;
7782         }
7783         return false;
7784     }
7785 
7786     /**
7787      * Used during creation of InstallArgs
7788      *
7789      * @param flags package installation flags
7790      * @return true if should be installed as forward locked
7791      */
installForwardLocked(int flags)7792     private static boolean installForwardLocked(int flags) {
7793         return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7794     }
7795 
createInstallArgs(InstallParams params)7796     private InstallArgs createInstallArgs(InstallParams params) {
7797         if (installOnSd(params.flags) || params.isForwardLocked()) {
7798             return new AsecInstallArgs(params);
7799         } else {
7800             return new FileInstallArgs(params);
7801         }
7802     }
7803 
createInstallArgs(int flags, String fullCodePath, String fullResourcePath, String nativeLibraryPath)7804     private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
7805             String nativeLibraryPath) {
7806         final boolean isInAsec;
7807         if (installOnSd(flags)) {
7808             /* Apps on SD card are always in ASEC containers. */
7809             isInAsec = true;
7810         } else if (installForwardLocked(flags)
7811                 && !fullCodePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
7812             /*
7813              * Forward-locked apps are only in ASEC containers if they're the
7814              * new style
7815              */
7816             isInAsec = true;
7817         } else {
7818             isInAsec = false;
7819         }
7820 
7821         if (isInAsec) {
7822             return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
7823                     installOnSd(flags), installForwardLocked(flags));
7824         } else {
7825             return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
7826         }
7827     }
7828 
7829     // Used by package mover
createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir)7830     private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
7831         if (installOnSd(flags) || installForwardLocked(flags)) {
7832             String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
7833                     + AsecInstallArgs.RES_FILE_NAME);
7834             return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
7835                     installForwardLocked(flags));
7836         } else {
7837             return new FileInstallArgs(packageURI, pkgName, dataDir);
7838         }
7839     }
7840 
7841     static abstract class InstallArgs {
7842         final IPackageInstallObserver observer;
7843         // Always refers to PackageManager flags only
7844         final int flags;
7845         final Uri packageURI;
7846         final String installerPackageName;
7847         final ManifestDigest manifestDigest;
7848         final UserHandle user;
7849 
InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, ManifestDigest manifestDigest, UserHandle user)7850         InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
7851                 String installerPackageName, ManifestDigest manifestDigest,
7852                 UserHandle user) {
7853             this.packageURI = packageURI;
7854             this.flags = flags;
7855             this.observer = observer;
7856             this.installerPackageName = installerPackageName;
7857             this.manifestDigest = manifestDigest;
7858             this.user = user;
7859         }
7860 
createCopyFile()7861         abstract void createCopyFile();
copyApk(IMediaContainerService imcs, boolean temp)7862         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
doPreInstall(int status)7863         abstract int doPreInstall(int status);
doRename(int status, String pkgName, String oldCodePath)7864         abstract boolean doRename(int status, String pkgName, String oldCodePath);
7865 
doPostInstall(int status, int uid)7866         abstract int doPostInstall(int status, int uid);
getCodePath()7867         abstract String getCodePath();
getResourcePath()7868         abstract String getResourcePath();
getNativeLibraryPath()7869         abstract String getNativeLibraryPath();
7870         // Need installer lock especially for dex file removal.
cleanUpResourcesLI()7871         abstract void cleanUpResourcesLI();
doPostDeleteLI(boolean delete)7872         abstract boolean doPostDeleteLI(boolean delete);
checkFreeStorage(IMediaContainerService imcs)7873         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
7874 
7875         /**
7876          * Called before the source arguments are copied. This is used mostly
7877          * for MoveParams when it needs to read the source file to put it in the
7878          * destination.
7879          */
doPreCopy()7880         int doPreCopy() {
7881             return PackageManager.INSTALL_SUCCEEDED;
7882         }
7883 
7884         /**
7885          * Called after the source arguments are copied. This is used mostly for
7886          * MoveParams when it needs to read the source file to put it in the
7887          * destination.
7888          *
7889          * @return
7890          */
doPostCopy(int uid)7891         int doPostCopy(int uid) {
7892             return PackageManager.INSTALL_SUCCEEDED;
7893         }
7894 
isFwdLocked()7895         protected boolean isFwdLocked() {
7896             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7897         }
7898 
getUser()7899         UserHandle getUser() {
7900             return user;
7901         }
7902     }
7903 
7904     class FileInstallArgs extends InstallArgs {
7905         File installDir;
7906         String codeFileName;
7907         String resourceFileName;
7908         String libraryPath;
7909         boolean created = false;
7910 
FileInstallArgs(InstallParams params)7911         FileInstallArgs(InstallParams params) {
7912             super(params.getPackageUri(), params.observer, params.flags,
7913                     params.installerPackageName, params.getManifestDigest(),
7914                     params.getUser());
7915         }
7916 
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath)7917         FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
7918             super(null, null, 0, null, null, null);
7919             File codeFile = new File(fullCodePath);
7920             installDir = codeFile.getParentFile();
7921             codeFileName = fullCodePath;
7922             resourceFileName = fullResourcePath;
7923             libraryPath = nativeLibraryPath;
7924         }
7925 
FileInstallArgs(Uri packageURI, String pkgName, String dataDir)7926         FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
7927             super(packageURI, null, 0, null, null, null);
7928             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
7929             String apkName = getNextCodePath(null, pkgName, ".apk");
7930             codeFileName = new File(installDir, apkName + ".apk").getPath();
7931             resourceFileName = getResourcePathFromCodePath();
7932             libraryPath = new File(mAppLibInstallDir, pkgName).getPath();
7933         }
7934 
checkFreeStorage(IMediaContainerService imcs)7935         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
7936             final long lowThreshold;
7937 
7938             final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
7939                     .getService(DeviceStorageMonitorService.SERVICE);
7940             if (dsm == null) {
7941                 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
7942                 lowThreshold = 0L;
7943             } else {
7944                 if (dsm.isMemoryLow()) {
7945                     Log.w(TAG, "Memory is reported as being too low; aborting package install");
7946                     return false;
7947                 }
7948 
7949                 lowThreshold = dsm.getMemoryLowThreshold();
7950             }
7951 
7952             try {
7953                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7954                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
7955                 return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold);
7956             } finally {
7957                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7958             }
7959         }
7960 
getCodePath()7961         String getCodePath() {
7962             return codeFileName;
7963         }
7964 
createCopyFile()7965         void createCopyFile() {
7966             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
7967             codeFileName = createTempPackageFile(installDir).getPath();
7968             resourceFileName = getResourcePathFromCodePath();
7969             libraryPath = getLibraryPathFromCodePath();
7970             created = true;
7971         }
7972 
copyApk(IMediaContainerService imcs, boolean temp)7973         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
7974             if (temp) {
7975                 // Generate temp file name
7976                 createCopyFile();
7977             }
7978             // Get a ParcelFileDescriptor to write to the output file
7979             File codeFile = new File(codeFileName);
7980             if (!created) {
7981                 try {
7982                     codeFile.createNewFile();
7983                     // Set permissions
7984                     if (!setPermissions()) {
7985                         // Failed setting permissions.
7986                         return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7987                     }
7988                 } catch (IOException e) {
7989                    Slog.w(TAG, "Failed to create file " + codeFile);
7990                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7991                 }
7992             }
7993             ParcelFileDescriptor out = null;
7994             try {
7995                 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
7996             } catch (FileNotFoundException e) {
7997                 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName);
7998                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7999             }
8000             // Copy the resource now
8001             int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8002             try {
8003                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
8004                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
8005                 ret = imcs.copyResource(packageURI, null, out);
8006             } finally {
8007                 IoUtils.closeQuietly(out);
8008                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
8009             }
8010 
8011             if (isFwdLocked()) {
8012                 final File destResourceFile = new File(getResourcePath());
8013 
8014                 // Copy the public files
8015                 try {
8016                     PackageHelper.extractPublicFiles(codeFileName, destResourceFile);
8017                 } catch (IOException e) {
8018                     Slog.e(TAG, "Couldn't create a new zip file for the public parts of a"
8019                             + " forward-locked app.");
8020                     destResourceFile.delete();
8021                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8022                 }
8023             }
8024 
8025             final File nativeLibraryFile = new File(getNativeLibraryPath());
8026             Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath());
8027             if (nativeLibraryFile.exists()) {
8028                 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
8029                 nativeLibraryFile.delete();
8030             }
8031             try {
8032                 int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
8033                 if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
8034                     return copyRet;
8035                 }
8036             } catch (IOException e) {
8037                 Slog.e(TAG, "Copying native libraries failed", e);
8038                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
8039             }
8040 
8041             return ret;
8042         }
8043 
doPreInstall(int status)8044         int doPreInstall(int status) {
8045             if (status != PackageManager.INSTALL_SUCCEEDED) {
8046                 cleanUp();
8047             }
8048             return status;
8049         }
8050 
doRename(int status, final String pkgName, String oldCodePath)8051         boolean doRename(int status, final String pkgName, String oldCodePath) {
8052             if (status != PackageManager.INSTALL_SUCCEEDED) {
8053                 cleanUp();
8054                 return false;
8055             } else {
8056                 final File oldCodeFile = new File(getCodePath());
8057                 final File oldResourceFile = new File(getResourcePath());
8058                 final File oldLibraryFile = new File(getNativeLibraryPath());
8059 
8060                 // Rename APK file based on packageName
8061                 final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
8062                 final File newCodeFile = new File(installDir, apkName + ".apk");
8063                 if (!oldCodeFile.renameTo(newCodeFile)) {
8064                     return false;
8065                 }
8066                 codeFileName = newCodeFile.getPath();
8067 
8068                 // Rename public resource file if it's forward-locked.
8069                 final File newResFile = new File(getResourcePathFromCodePath());
8070                 if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
8071                     return false;
8072                 }
8073                 resourceFileName = newResFile.getPath();
8074 
8075                 // Rename library path
8076                 final File newLibraryFile = new File(getLibraryPathFromCodePath());
8077                 if (newLibraryFile.exists()) {
8078                     NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile);
8079                     newLibraryFile.delete();
8080                 }
8081                 if (!oldLibraryFile.renameTo(newLibraryFile)) {
8082                     Slog.e(TAG, "Cannot rename native library directory "
8083                             + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath());
8084                     return false;
8085                 }
8086                 libraryPath = newLibraryFile.getPath();
8087 
8088                 // Attempt to set permissions
8089                 if (!setPermissions()) {
8090                     return false;
8091                 }
8092 
8093                 if (!SELinux.restorecon(newCodeFile)) {
8094                     return false;
8095                 }
8096 
8097                 return true;
8098             }
8099         }
8100 
doPostInstall(int status, int uid)8101         int doPostInstall(int status, int uid) {
8102             if (status != PackageManager.INSTALL_SUCCEEDED) {
8103                 cleanUp();
8104             }
8105             return status;
8106         }
8107 
getResourcePath()8108         String getResourcePath() {
8109             return resourceFileName;
8110         }
8111 
getResourcePathFromCodePath()8112         private String getResourcePathFromCodePath() {
8113             final String codePath = getCodePath();
8114             if (isFwdLocked()) {
8115                 final StringBuilder sb = new StringBuilder();
8116 
8117                 sb.append(mAppInstallDir.getPath());
8118                 sb.append('/');
8119                 sb.append(getApkName(codePath));
8120                 sb.append(".zip");
8121 
8122                 /*
8123                  * If our APK is a temporary file, mark the resource as a
8124                  * temporary file as well so it can be cleaned up after
8125                  * catastrophic failure.
8126                  */
8127                 if (codePath.endsWith(".tmp")) {
8128                     sb.append(".tmp");
8129                 }
8130 
8131                 return sb.toString();
8132             } else {
8133                 return codePath;
8134             }
8135         }
8136 
getLibraryPathFromCodePath()8137         private String getLibraryPathFromCodePath() {
8138             return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath();
8139         }
8140 
8141         @Override
getNativeLibraryPath()8142         String getNativeLibraryPath() {
8143             if (libraryPath == null) {
8144                 libraryPath = getLibraryPathFromCodePath();
8145             }
8146             return libraryPath;
8147         }
8148 
cleanUp()8149         private boolean cleanUp() {
8150             boolean ret = true;
8151             String sourceDir = getCodePath();
8152             String publicSourceDir = getResourcePath();
8153             if (sourceDir != null) {
8154                 File sourceFile = new File(sourceDir);
8155                 if (!sourceFile.exists()) {
8156                     Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
8157                     ret = false;
8158                 }
8159                 // Delete application's code and resources
8160                 sourceFile.delete();
8161             }
8162             if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
8163                 final File publicSourceFile = new File(publicSourceDir);
8164                 if (!publicSourceFile.exists()) {
8165                     Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
8166                 }
8167                 if (publicSourceFile.exists()) {
8168                     publicSourceFile.delete();
8169                 }
8170             }
8171 
8172             if (libraryPath != null) {
8173                 File nativeLibraryFile = new File(libraryPath);
8174                 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
8175                 if (!nativeLibraryFile.delete()) {
8176                     Slog.w(TAG, "Couldn't delete native library directory " + libraryPath);
8177                 }
8178             }
8179 
8180             return ret;
8181         }
8182 
cleanUpResourcesLI()8183         void cleanUpResourcesLI() {
8184             String sourceDir = getCodePath();
8185             if (cleanUp()) {
8186                 int retCode = mInstaller.rmdex(sourceDir);
8187                 if (retCode < 0) {
8188                     Slog.w(TAG, "Couldn't remove dex file for package: "
8189                             +  " at location "
8190                             + sourceDir + ", retcode=" + retCode);
8191                     // we don't consider this to be a failure of the core package deletion
8192                 }
8193             }
8194         }
8195 
setPermissions()8196         private boolean setPermissions() {
8197             // TODO Do this in a more elegant way later on. for now just a hack
8198             if (!isFwdLocked()) {
8199                 final int filePermissions =
8200                     FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
8201                     |FileUtils.S_IROTH;
8202                 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
8203                 if (retCode != 0) {
8204                     Slog.e(TAG, "Couldn't set new package file permissions for " +
8205                             getCodePath()
8206                             + ". The return code was: " + retCode);
8207                     // TODO Define new internal error
8208                     return false;
8209                 }
8210                 return true;
8211             }
8212             return true;
8213         }
8214 
doPostDeleteLI(boolean delete)8215         boolean doPostDeleteLI(boolean delete) {
8216             // XXX err, shouldn't we respect the delete flag?
8217             cleanUpResourcesLI();
8218             return true;
8219         }
8220     }
8221 
isAsecExternal(String cid)8222     private boolean isAsecExternal(String cid) {
8223         final String asecPath = PackageHelper.getSdFilesystem(cid);
8224         return !asecPath.startsWith(mAsecInternalPath);
8225     }
8226 
8227     /**
8228      * Extract the MountService "container ID" from the full code path of an
8229      * .apk.
8230      */
cidFromCodePath(String fullCodePath)8231     static String cidFromCodePath(String fullCodePath) {
8232         int eidx = fullCodePath.lastIndexOf("/");
8233         String subStr1 = fullCodePath.substring(0, eidx);
8234         int sidx = subStr1.lastIndexOf("/");
8235         return subStr1.substring(sidx+1, eidx);
8236     }
8237 
8238     class AsecInstallArgs extends InstallArgs {
8239         static final String RES_FILE_NAME = "pkg.apk";
8240         static final String PUBLIC_RES_FILE_NAME = "res.zip";
8241 
8242         String cid;
8243         String packagePath;
8244         String resourcePath;
8245         String libraryPath;
8246 
AsecInstallArgs(InstallParams params)8247         AsecInstallArgs(InstallParams params) {
8248             super(params.getPackageUri(), params.observer, params.flags,
8249                     params.installerPackageName, params.getManifestDigest(),
8250                     params.getUser());
8251         }
8252 
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, boolean isExternal, boolean isForwardLocked)8253         AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
8254                 boolean isExternal, boolean isForwardLocked) {
8255             super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
8256                     | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
8257                     null, null, null);
8258             // Extract cid from fullCodePath
8259             int eidx = fullCodePath.lastIndexOf("/");
8260             String subStr1 = fullCodePath.substring(0, eidx);
8261             int sidx = subStr1.lastIndexOf("/");
8262             cid = subStr1.substring(sidx+1, eidx);
8263             setCachePath(subStr1);
8264         }
8265 
AsecInstallArgs(String cid, boolean isForwardLocked)8266         AsecInstallArgs(String cid, boolean isForwardLocked) {
8267             super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
8268                     | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
8269                     null, null, null);
8270             this.cid = cid;
8271             setCachePath(PackageHelper.getSdDir(cid));
8272         }
8273 
AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked)8274         AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
8275             super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
8276                     | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
8277                     null, null, null);
8278             this.cid = cid;
8279         }
8280 
createCopyFile()8281         void createCopyFile() {
8282             cid = getTempContainerId();
8283         }
8284 
checkFreeStorage(IMediaContainerService imcs)8285         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
8286             try {
8287                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
8288                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
8289                 return imcs.checkExternalFreeStorage(packageURI, isFwdLocked());
8290             } finally {
8291                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
8292             }
8293         }
8294 
isExternal()8295         private final boolean isExternal() {
8296             return (flags & PackageManager.INSTALL_EXTERNAL) != 0;
8297         }
8298 
copyApk(IMediaContainerService imcs, boolean temp)8299         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
8300             if (temp) {
8301                 createCopyFile();
8302             } else {
8303                 /*
8304                  * Pre-emptively destroy the container since it's destroyed if
8305                  * copying fails due to it existing anyway.
8306                  */
8307                 PackageHelper.destroySdDir(cid);
8308             }
8309 
8310             final String newCachePath;
8311             try {
8312                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
8313                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
8314                 newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(),
8315                         RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked());
8316             } finally {
8317                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
8318             }
8319 
8320             if (newCachePath != null) {
8321                 setCachePath(newCachePath);
8322                 return PackageManager.INSTALL_SUCCEEDED;
8323             } else {
8324                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8325             }
8326         }
8327 
8328         @Override
getCodePath()8329         String getCodePath() {
8330             return packagePath;
8331         }
8332 
8333         @Override
getResourcePath()8334         String getResourcePath() {
8335             return resourcePath;
8336         }
8337 
8338         @Override
getNativeLibraryPath()8339         String getNativeLibraryPath() {
8340             return libraryPath;
8341         }
8342 
doPreInstall(int status)8343         int doPreInstall(int status) {
8344             if (status != PackageManager.INSTALL_SUCCEEDED) {
8345                 // Destroy container
8346                 PackageHelper.destroySdDir(cid);
8347             } else {
8348                 boolean mounted = PackageHelper.isContainerMounted(cid);
8349                 if (!mounted) {
8350                     String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
8351                             Process.SYSTEM_UID);
8352                     if (newCachePath != null) {
8353                         setCachePath(newCachePath);
8354                     } else {
8355                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8356                     }
8357                 }
8358             }
8359             return status;
8360         }
8361 
doRename(int status, final String pkgName, String oldCodePath)8362         boolean doRename(int status, final String pkgName,
8363                 String oldCodePath) {
8364             String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
8365             String newCachePath = null;
8366             if (PackageHelper.isContainerMounted(cid)) {
8367                 // Unmount the container
8368                 if (!PackageHelper.unMountSdDir(cid)) {
8369                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
8370                     return false;
8371                 }
8372             }
8373             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
8374                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
8375                         " which might be stale. Will try to clean up.");
8376                 // Clean up the stale container and proceed to recreate.
8377                 if (!PackageHelper.destroySdDir(newCacheId)) {
8378                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
8379                     return false;
8380                 }
8381                 // Successfully cleaned up stale container. Try to rename again.
8382                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
8383                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
8384                             + " inspite of cleaning it up.");
8385                     return false;
8386                 }
8387             }
8388             if (!PackageHelper.isContainerMounted(newCacheId)) {
8389                 Slog.w(TAG, "Mounting container " + newCacheId);
8390                 newCachePath = PackageHelper.mountSdDir(newCacheId,
8391                         getEncryptKey(), Process.SYSTEM_UID);
8392             } else {
8393                 newCachePath = PackageHelper.getSdDir(newCacheId);
8394             }
8395             if (newCachePath == null) {
8396                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
8397                 return false;
8398             }
8399             Log.i(TAG, "Succesfully renamed " + cid +
8400                     " to " + newCacheId +
8401                     " at new path: " + newCachePath);
8402             cid = newCacheId;
8403             setCachePath(newCachePath);
8404             return true;
8405         }
8406 
setCachePath(String newCachePath)8407         private void setCachePath(String newCachePath) {
8408             File cachePath = new File(newCachePath);
8409             libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
8410             packagePath = new File(cachePath, RES_FILE_NAME).getPath();
8411 
8412             if (isFwdLocked()) {
8413                 resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath();
8414             } else {
8415                 resourcePath = packagePath;
8416             }
8417         }
8418 
doPostInstall(int status, int uid)8419         int doPostInstall(int status, int uid) {
8420             if (status != PackageManager.INSTALL_SUCCEEDED) {
8421                 cleanUp();
8422             } else {
8423                 final int groupOwner;
8424                 final String protectedFile;
8425                 if (isFwdLocked()) {
8426                     groupOwner = UserHandle.getSharedAppGid(uid);
8427                     protectedFile = RES_FILE_NAME;
8428                 } else {
8429                     groupOwner = -1;
8430                     protectedFile = null;
8431                 }
8432 
8433                 if (uid < Process.FIRST_APPLICATION_UID
8434                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
8435                     Slog.e(TAG, "Failed to finalize " + cid);
8436                     PackageHelper.destroySdDir(cid);
8437                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8438                 }
8439 
8440                 boolean mounted = PackageHelper.isContainerMounted(cid);
8441                 if (!mounted) {
8442                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
8443                 }
8444             }
8445             return status;
8446         }
8447 
cleanUp()8448         private void cleanUp() {
8449             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
8450 
8451             // Destroy secure container
8452             PackageHelper.destroySdDir(cid);
8453         }
8454 
cleanUpResourcesLI()8455         void cleanUpResourcesLI() {
8456             String sourceFile = getCodePath();
8457             // Remove dex file
8458             int retCode = mInstaller.rmdex(sourceFile);
8459             if (retCode < 0) {
8460                 Slog.w(TAG, "Couldn't remove dex file for package: "
8461                         + " at location "
8462                         + sourceFile.toString() + ", retcode=" + retCode);
8463                 // we don't consider this to be a failure of the core package deletion
8464             }
8465             cleanUp();
8466         }
8467 
matchContainer(String app)8468         boolean matchContainer(String app) {
8469             if (cid.startsWith(app)) {
8470                 return true;
8471             }
8472             return false;
8473         }
8474 
getPackageName()8475         String getPackageName() {
8476             return getAsecPackageName(cid);
8477         }
8478 
doPostDeleteLI(boolean delete)8479         boolean doPostDeleteLI(boolean delete) {
8480             boolean ret = false;
8481             boolean mounted = PackageHelper.isContainerMounted(cid);
8482             if (mounted) {
8483                 // Unmount first
8484                 ret = PackageHelper.unMountSdDir(cid);
8485             }
8486             if (ret && delete) {
8487                 cleanUpResourcesLI();
8488             }
8489             return ret;
8490         }
8491 
8492         @Override
doPreCopy()8493         int doPreCopy() {
8494             if (isFwdLocked()) {
8495                 if (!PackageHelper.fixSdPermissions(cid,
8496                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
8497                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8498                 }
8499             }
8500 
8501             return PackageManager.INSTALL_SUCCEEDED;
8502         }
8503 
8504         @Override
doPostCopy(int uid)8505         int doPostCopy(int uid) {
8506             if (isFwdLocked()) {
8507                 if (uid < Process.FIRST_APPLICATION_UID
8508                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
8509                                 RES_FILE_NAME)) {
8510                     Slog.e(TAG, "Failed to finalize " + cid);
8511                     PackageHelper.destroySdDir(cid);
8512                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8513                 }
8514             }
8515 
8516             return PackageManager.INSTALL_SUCCEEDED;
8517         }
8518     };
8519 
getAsecPackageName(String packageCid)8520     static String getAsecPackageName(String packageCid) {
8521         int idx = packageCid.lastIndexOf("-");
8522         if (idx == -1) {
8523             return packageCid;
8524         }
8525         return packageCid.substring(0, idx);
8526     }
8527 
8528     // Utility method used to create code paths based on package name and available index.
getNextCodePath(String oldCodePath, String prefix, String suffix)8529     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
8530         String idxStr = "";
8531         int idx = 1;
8532         // Fall back to default value of idx=1 if prefix is not
8533         // part of oldCodePath
8534         if (oldCodePath != null) {
8535             String subStr = oldCodePath;
8536             // Drop the suffix right away
8537             if (subStr.endsWith(suffix)) {
8538                 subStr = subStr.substring(0, subStr.length() - suffix.length());
8539             }
8540             // If oldCodePath already contains prefix find out the
8541             // ending index to either increment or decrement.
8542             int sidx = subStr.lastIndexOf(prefix);
8543             if (sidx != -1) {
8544                 subStr = subStr.substring(sidx + prefix.length());
8545                 if (subStr != null) {
8546                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
8547                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
8548                     }
8549                     try {
8550                         idx = Integer.parseInt(subStr);
8551                         if (idx <= 1) {
8552                             idx++;
8553                         } else {
8554                             idx--;
8555                         }
8556                     } catch(NumberFormatException e) {
8557                     }
8558                 }
8559             }
8560         }
8561         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
8562         return prefix + idxStr;
8563     }
8564 
8565     // Utility method used to ignore ADD/REMOVE events
8566     // by directory observer.
ignoreCodePath(String fullPathStr)8567     private static boolean ignoreCodePath(String fullPathStr) {
8568         String apkName = getApkName(fullPathStr);
8569         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
8570         if (idx != -1 && ((idx+1) < apkName.length())) {
8571             // Make sure the package ends with a numeral
8572             String version = apkName.substring(idx+1);
8573             try {
8574                 Integer.parseInt(version);
8575                 return true;
8576             } catch (NumberFormatException e) {}
8577         }
8578         return false;
8579     }
8580 
8581     // Utility method that returns the relative package path with respect
8582     // to the installation directory. Like say for /data/data/com.test-1.apk
8583     // string com.test-1 is returned.
getApkName(String codePath)8584     static String getApkName(String codePath) {
8585         if (codePath == null) {
8586             return null;
8587         }
8588         int sidx = codePath.lastIndexOf("/");
8589         int eidx = codePath.lastIndexOf(".");
8590         if (eidx == -1) {
8591             eidx = codePath.length();
8592         } else if (eidx == 0) {
8593             Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
8594             return null;
8595         }
8596         return codePath.substring(sidx+1, eidx);
8597     }
8598 
8599     class PackageInstalledInfo {
8600         String name;
8601         int uid;
8602         // The set of users that originally had this package installed.
8603         int[] origUsers;
8604         // The set of users that now have this package installed.
8605         int[] newUsers;
8606         PackageParser.Package pkg;
8607         int returnCode;
8608         PackageRemovedInfo removedInfo;
8609     }
8610 
8611     /*
8612      * Install a non-existing package.
8613      */
installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, String installerPackageName, PackageInstalledInfo res)8614     private void installNewPackageLI(PackageParser.Package pkg,
8615             int parseFlags, int scanMode, UserHandle user,
8616             String installerPackageName, PackageInstalledInfo res) {
8617         // Remember this for later, in case we need to rollback this install
8618         String pkgName = pkg.packageName;
8619 
8620         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
8621         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
8622         synchronized(mPackages) {
8623             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
8624                 // A package with the same name is already installed, though
8625                 // it has been renamed to an older name.  The package we
8626                 // are trying to install should be installed as an update to
8627                 // the existing one, but that has not been requested, so bail.
8628                 Slog.w(TAG, "Attempt to re-install " + pkgName
8629                         + " without first uninstalling package running as "
8630                         + mSettings.mRenamedPackages.get(pkgName));
8631                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8632                 return;
8633             }
8634             if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
8635                 // Don't allow installation over an existing package with the same name.
8636                 Slog.w(TAG, "Attempt to re-install " + pkgName
8637                         + " without first uninstalling.");
8638                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8639                 return;
8640             }
8641         }
8642         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8643         PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
8644                 System.currentTimeMillis(), user);
8645         if (newPackage == null) {
8646             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8647             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8648                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8649             }
8650         } else {
8651             updateSettingsLI(newPackage,
8652                     installerPackageName,
8653                     null, null,
8654                     res);
8655             // delete the partially installed application. the data directory will have to be
8656             // restored if it was already existing
8657             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8658                 // remove package from internal structures.  Note that we want deletePackageX to
8659                 // delete the package data and cache directories that it created in
8660                 // scanPackageLocked, unless those directories existed before we even tried to
8661                 // install.
8662                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
8663                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
8664                                 res.removedInfo, true);
8665             }
8666         }
8667     }
8668 
replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, String installerPackageName, PackageInstalledInfo res)8669     private void replacePackageLI(PackageParser.Package pkg,
8670             int parseFlags, int scanMode, UserHandle user,
8671             String installerPackageName, PackageInstalledInfo res) {
8672 
8673         PackageParser.Package oldPackage;
8674         String pkgName = pkg.packageName;
8675         int[] allUsers;
8676         boolean[] perUserInstalled;
8677 
8678         // First find the old package info and check signatures
8679         synchronized(mPackages) {
8680             oldPackage = mPackages.get(pkgName);
8681             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
8682             if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
8683                     != PackageManager.SIGNATURE_MATCH) {
8684                 Slog.w(TAG, "New package has a different signature: " + pkgName);
8685                 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
8686                 return;
8687             }
8688 
8689             // In case of rollback, remember per-user/profile install state
8690             PackageSetting ps = mSettings.mPackages.get(pkgName);
8691             allUsers = sUserManager.getUserIds();
8692             perUserInstalled = new boolean[allUsers.length];
8693             for (int i = 0; i < allUsers.length; i++) {
8694                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
8695             }
8696         }
8697         boolean sysPkg = (isSystemApp(oldPackage));
8698         if (sysPkg) {
8699             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
8700                     user, allUsers, perUserInstalled, installerPackageName, res);
8701         } else {
8702             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
8703                     user, allUsers, perUserInstalled, installerPackageName, res);
8704         }
8705     }
8706 
replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, PackageInstalledInfo res)8707     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
8708             PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
8709             int[] allUsers, boolean[] perUserInstalled,
8710             String installerPackageName, PackageInstalledInfo res) {
8711         PackageParser.Package newPackage = null;
8712         String pkgName = deletedPackage.packageName;
8713         boolean deletedPkg = true;
8714         boolean updatedSettings = false;
8715 
8716         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
8717                 + deletedPackage);
8718         long origUpdateTime;
8719         if (pkg.mExtras != null) {
8720             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
8721         } else {
8722             origUpdateTime = 0;
8723         }
8724 
8725         // First delete the existing package while retaining the data directory
8726         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
8727                 res.removedInfo, true)) {
8728             // If the existing package wasn't successfully deleted
8729             res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
8730             deletedPkg = false;
8731         } else {
8732             // Successfully deleted the old package. Now proceed with re-installation
8733             mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8734             newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
8735                     System.currentTimeMillis(), user);
8736             if (newPackage == null) {
8737                 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8738                 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8739                     res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8740                 }
8741             } else {
8742                 updateSettingsLI(newPackage,
8743                         installerPackageName,
8744                         allUsers, perUserInstalled,
8745                         res);
8746                 updatedSettings = true;
8747             }
8748         }
8749 
8750         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8751             // remove package from internal structures.  Note that we want deletePackageX to
8752             // delete the package data and cache directories that it created in
8753             // scanPackageLocked, unless those directories existed before we even tried to
8754             // install.
8755             if(updatedSettings) {
8756                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
8757                 deletePackageLI(
8758                         pkgName, null, true, allUsers, perUserInstalled,
8759                         PackageManager.DELETE_KEEP_DATA,
8760                                 res.removedInfo, true);
8761             }
8762             // Since we failed to install the new package we need to restore the old
8763             // package that we deleted.
8764             if(deletedPkg) {
8765                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
8766                 File restoreFile = new File(deletedPackage.mPath);
8767                 // Parse old package
8768                 boolean oldOnSd = isExternal(deletedPackage);
8769                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
8770                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
8771                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
8772                 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
8773                         | SCAN_UPDATE_TIME;
8774                 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
8775                         origUpdateTime, null) == null) {
8776                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
8777                     return;
8778                 }
8779                 // Restore of old package succeeded. Update permissions.
8780                 // writer
8781                 synchronized (mPackages) {
8782                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
8783                             UPDATE_PERMISSIONS_ALL);
8784                     // can downgrade to reader
8785                     mSettings.writeLPr();
8786                 }
8787                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
8788             }
8789         }
8790     }
8791 
replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, PackageInstalledInfo res)8792     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
8793             PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
8794             int[] allUsers, boolean[] perUserInstalled,
8795             String installerPackageName, PackageInstalledInfo res) {
8796         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
8797                 + ", old=" + deletedPackage);
8798         PackageParser.Package newPackage = null;
8799         boolean updatedSettings = false;
8800         parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
8801                 PackageParser.PARSE_IS_SYSTEM;
8802         if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
8803             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8804         }
8805         String packageName = deletedPackage.packageName;
8806         res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
8807         if (packageName == null) {
8808             Slog.w(TAG, "Attempt to delete null packageName.");
8809             return;
8810         }
8811         PackageParser.Package oldPkg;
8812         PackageSetting oldPkgSetting;
8813         // reader
8814         synchronized (mPackages) {
8815             oldPkg = mPackages.get(packageName);
8816             oldPkgSetting = mSettings.mPackages.get(packageName);
8817             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
8818                     (oldPkgSetting == null)) {
8819                 Slog.w(TAG, "Couldn't find package:"+packageName+" information");
8820                 return;
8821             }
8822         }
8823 
8824         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
8825 
8826         res.removedInfo.uid = oldPkg.applicationInfo.uid;
8827         res.removedInfo.removedPackage = packageName;
8828         // Remove existing system package
8829         removePackageLI(oldPkgSetting, true);
8830         // writer
8831         synchronized (mPackages) {
8832             if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
8833                 // We didn't need to disable the .apk as a current system package,
8834                 // which means we are replacing another update that is already
8835                 // installed.  We need to make sure to delete the older one's .apk.
8836                 res.removedInfo.args = createInstallArgs(0,
8837                         deletedPackage.applicationInfo.sourceDir,
8838                         deletedPackage.applicationInfo.publicSourceDir,
8839                         deletedPackage.applicationInfo.nativeLibraryDir);
8840             } else {
8841                 res.removedInfo.args = null;
8842             }
8843         }
8844 
8845         // Successfully disabled the old package. Now proceed with re-installation
8846         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8847         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
8848         newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);
8849         if (newPackage == null) {
8850             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8851             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8852                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8853             }
8854         } else {
8855             if (newPackage.mExtras != null) {
8856                 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
8857                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
8858                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
8859             }
8860             updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
8861             updatedSettings = true;
8862         }
8863 
8864         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8865             // Re installation failed. Restore old information
8866             // Remove new pkg information
8867             if (newPackage != null) {
8868                 removeInstalledPackageLI(newPackage, true);
8869             }
8870             // Add back the old system package
8871             scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
8872             // Restore the old system information in Settings
8873             synchronized(mPackages) {
8874                 if (updatedSettings) {
8875                     mSettings.enableSystemPackageLPw(packageName);
8876                     mSettings.setInstallerPackageName(packageName,
8877                             oldPkgSetting.installerPackageName);
8878                 }
8879                 mSettings.writeLPr();
8880             }
8881         }
8882     }
8883 
8884     // Utility method used to move dex files during install.
moveDexFilesLI(PackageParser.Package newPackage)8885     private int moveDexFilesLI(PackageParser.Package newPackage) {
8886         int retCode;
8887         if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
8888             retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
8889             if (retCode != 0) {
8890                 if (mNoDexOpt) {
8891                     /*
8892                      * If we're in an engineering build, programs are lazily run
8893                      * through dexopt. If the .dex file doesn't exist yet, it
8894                      * will be created when the program is run next.
8895                      */
8896                     Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
8897                 } else {
8898                     Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
8899                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8900                 }
8901             }
8902         }
8903         return PackageManager.INSTALL_SUCCEEDED;
8904     }
8905 
updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res)8906     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
8907             int[] allUsers, boolean[] perUserInstalled,
8908             PackageInstalledInfo res) {
8909         String pkgName = newPackage.packageName;
8910         synchronized (mPackages) {
8911             //write settings. the installStatus will be incomplete at this stage.
8912             //note that the new package setting would have already been
8913             //added to mPackages. It hasn't been persisted yet.
8914             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
8915             mSettings.writeLPr();
8916         }
8917 
8918         if ((res.returnCode = moveDexFilesLI(newPackage))
8919                 != PackageManager.INSTALL_SUCCEEDED) {
8920             // Discontinue if moving dex files failed.
8921             return;
8922         }
8923 
8924         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.mPath);
8925 
8926         synchronized (mPackages) {
8927             updatePermissionsLPw(newPackage.packageName, newPackage,
8928                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
8929                             ? UPDATE_PERMISSIONS_ALL : 0));
8930             // For system-bundled packages, we assume that installing an upgraded version
8931             // of the package implies that the user actually wants to run that new code,
8932             // so we enable the package.
8933             if (isSystemApp(newPackage)) {
8934                 // NB: implicit assumption that system package upgrades apply to all users
8935                 if (DEBUG_INSTALL) {
8936                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
8937                 }
8938                 PackageSetting ps = mSettings.mPackages.get(pkgName);
8939                 if (ps != null) {
8940                     if (res.origUsers != null) {
8941                         for (int userHandle : res.origUsers) {
8942                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
8943                                     userHandle, installerPackageName);
8944                         }
8945                     }
8946                     // Also convey the prior install/uninstall state
8947                     if (allUsers != null && perUserInstalled != null) {
8948                         for (int i = 0; i < allUsers.length; i++) {
8949                             if (DEBUG_INSTALL) {
8950                                 Slog.d(TAG, "    user " + allUsers[i]
8951                                         + " => " + perUserInstalled[i]);
8952                             }
8953                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
8954                         }
8955                         // these install state changes will be persisted in the
8956                         // upcoming call to mSettings.writeLPr().
8957                     }
8958                 }
8959             }
8960             res.name = pkgName;
8961             res.uid = newPackage.applicationInfo.uid;
8962             res.pkg = newPackage;
8963             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
8964             mSettings.setInstallerPackageName(pkgName, installerPackageName);
8965             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
8966             //to update install status
8967             mSettings.writeLPr();
8968         }
8969     }
8970 
installPackageLI(InstallArgs args, boolean newInstall, PackageInstalledInfo res)8971     private void installPackageLI(InstallArgs args,
8972             boolean newInstall, PackageInstalledInfo res) {
8973         int pFlags = args.flags;
8974         String installerPackageName = args.installerPackageName;
8975         File tmpPackageFile = new File(args.getCodePath());
8976         boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
8977         boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
8978         boolean replace = false;
8979         int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
8980                 | (newInstall ? SCAN_NEW_INSTALL : 0);
8981         // Result object to be returned
8982         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
8983 
8984         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
8985         // Retrieve PackageSettings and parse package
8986         int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
8987                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
8988                 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
8989         PackageParser pp = new PackageParser(tmpPackageFile.getPath());
8990         pp.setSeparateProcesses(mSeparateProcesses);
8991         final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
8992                 null, mMetrics, parseFlags);
8993         if (pkg == null) {
8994             res.returnCode = pp.getParseError();
8995             return;
8996         }
8997         String pkgName = res.name = pkg.packageName;
8998         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
8999             if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
9000                 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
9001                 return;
9002             }
9003         }
9004         if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
9005             res.returnCode = pp.getParseError();
9006             return;
9007         }
9008 
9009         /* If the installer passed in a manifest digest, compare it now. */
9010         if (args.manifestDigest != null) {
9011             if (DEBUG_INSTALL) {
9012                 final String parsedManifest = pkg.manifestDigest == null ? "null"
9013                         : pkg.manifestDigest.toString();
9014                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
9015                         + parsedManifest);
9016             }
9017 
9018             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
9019                 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
9020                 return;
9021             }
9022         } else if (DEBUG_INSTALL) {
9023             final String parsedManifest = pkg.manifestDigest == null
9024                     ? "null" : pkg.manifestDigest.toString();
9025             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
9026         }
9027 
9028         // Get rid of all references to package scan path via parser.
9029         pp = null;
9030         String oldCodePath = null;
9031         boolean systemApp = false;
9032         synchronized (mPackages) {
9033             // Check if installing already existing package
9034             if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
9035                 String oldName = mSettings.mRenamedPackages.get(pkgName);
9036                 if (pkg.mOriginalPackages != null
9037                         && pkg.mOriginalPackages.contains(oldName)
9038                         && mPackages.containsKey(oldName)) {
9039                     // This package is derived from an original package,
9040                     // and this device has been updating from that original
9041                     // name.  We must continue using the original name, so
9042                     // rename the new package here.
9043                     pkg.setPackageName(oldName);
9044                     pkgName = pkg.packageName;
9045                     replace = true;
9046                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
9047                             + oldName + " pkgName=" + pkgName);
9048                 } else if (mPackages.containsKey(pkgName)) {
9049                     // This package, under its official name, already exists
9050                     // on the device; we should replace it.
9051                     replace = true;
9052                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
9053                 }
9054             }
9055             PackageSetting ps = mSettings.mPackages.get(pkgName);
9056             if (ps != null) {
9057                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
9058                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
9059                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
9060                     systemApp = (ps.pkg.applicationInfo.flags &
9061                             ApplicationInfo.FLAG_SYSTEM) != 0;
9062                 }
9063                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
9064             }
9065         }
9066 
9067         if (systemApp && onSd) {
9068             // Disable updates to system apps on sdcard
9069             Slog.w(TAG, "Cannot install updates to system apps on sdcard");
9070             res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
9071             return;
9072         }
9073 
9074         if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
9075             res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9076             return;
9077         }
9078         // Set application objects path explicitly after the rename
9079         setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
9080         pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
9081         if (replace) {
9082             replacePackageLI(pkg, parseFlags, scanMode, args.user,
9083                     installerPackageName, res);
9084         } else {
9085             installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user,
9086                     installerPackageName, res);
9087         }
9088         synchronized (mPackages) {
9089             final PackageSetting ps = mSettings.mPackages.get(pkgName);
9090             if (ps != null) {
9091                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
9092             }
9093         }
9094     }
9095 
isForwardLocked(PackageParser.Package pkg)9096     private static boolean isForwardLocked(PackageParser.Package pkg) {
9097         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
9098     }
9099 
9100 
isForwardLocked(PackageSetting ps)9101     private boolean isForwardLocked(PackageSetting ps) {
9102         return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
9103     }
9104 
isExternal(PackageParser.Package pkg)9105     private static boolean isExternal(PackageParser.Package pkg) {
9106         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
9107     }
9108 
isExternal(PackageSetting ps)9109     private static boolean isExternal(PackageSetting ps) {
9110         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
9111     }
9112 
isSystemApp(PackageParser.Package pkg)9113     private static boolean isSystemApp(PackageParser.Package pkg) {
9114         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
9115     }
9116 
isPrivilegedApp(PackageParser.Package pkg)9117     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
9118         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
9119     }
9120 
isSystemApp(ApplicationInfo info)9121     private static boolean isSystemApp(ApplicationInfo info) {
9122         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
9123     }
9124 
isSystemApp(PackageSetting ps)9125     private static boolean isSystemApp(PackageSetting ps) {
9126         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
9127     }
9128 
isUpdatedSystemApp(PackageSetting ps)9129     private static boolean isUpdatedSystemApp(PackageSetting ps) {
9130         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
9131     }
9132 
isUpdatedSystemApp(PackageParser.Package pkg)9133     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
9134         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
9135     }
9136 
packageFlagsToInstallFlags(PackageSetting ps)9137     private int packageFlagsToInstallFlags(PackageSetting ps) {
9138         int installFlags = 0;
9139         if (isExternal(ps)) {
9140             installFlags |= PackageManager.INSTALL_EXTERNAL;
9141         }
9142         if (isForwardLocked(ps)) {
9143             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
9144         }
9145         return installFlags;
9146     }
9147 
deleteTempPackageFiles()9148     private void deleteTempPackageFiles() {
9149         final FilenameFilter filter = new FilenameFilter() {
9150             public boolean accept(File dir, String name) {
9151                 return name.startsWith("vmdl") && name.endsWith(".tmp");
9152             }
9153         };
9154         deleteTempPackageFilesInDirectory(mAppInstallDir, filter);
9155         deleteTempPackageFilesInDirectory(mDrmAppPrivateInstallDir, filter);
9156     }
9157 
deleteTempPackageFilesInDirectory(File directory, FilenameFilter filter)9158     private static final void deleteTempPackageFilesInDirectory(File directory,
9159             FilenameFilter filter) {
9160         final String[] tmpFilesList = directory.list(filter);
9161         if (tmpFilesList == null) {
9162             return;
9163         }
9164         for (int i = 0; i < tmpFilesList.length; i++) {
9165             final File tmpFile = new File(directory, tmpFilesList[i]);
9166             tmpFile.delete();
9167         }
9168     }
9169 
createTempPackageFile(File installDir)9170     private File createTempPackageFile(File installDir) {
9171         File tmpPackageFile;
9172         try {
9173             tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir);
9174         } catch (IOException e) {
9175             Slog.e(TAG, "Couldn't create temp file for downloaded package file.");
9176             return null;
9177         }
9178         try {
9179             FileUtils.setPermissions(
9180                     tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
9181                     -1, -1);
9182             if (!SELinux.restorecon(tmpPackageFile)) {
9183                 return null;
9184             }
9185         } catch (IOException e) {
9186             Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
9187             return null;
9188         }
9189         return tmpPackageFile;
9190     }
9191 
9192     @Override
deletePackageAsUser(final String packageName, final IPackageDeleteObserver observer, final int userId, final int flags)9193     public void deletePackageAsUser(final String packageName,
9194                                     final IPackageDeleteObserver observer,
9195                                     final int userId, final int flags) {
9196         mContext.enforceCallingOrSelfPermission(
9197                 android.Manifest.permission.DELETE_PACKAGES, null);
9198         final int uid = Binder.getCallingUid();
9199         if (UserHandle.getUserId(uid) != userId) {
9200             mContext.enforceCallingPermission(
9201                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9202                     "deletePackage for user " + userId);
9203         }
9204         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
9205             try {
9206                 observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED);
9207             } catch (RemoteException re) {
9208             }
9209             return;
9210         }
9211 
9212         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
9213         // Queue up an async operation since the package deletion may take a little while.
9214         mHandler.post(new Runnable() {
9215             public void run() {
9216                 mHandler.removeCallbacks(this);
9217                 final int returnCode = deletePackageX(packageName, userId, flags);
9218                 if (observer != null) {
9219                     try {
9220                         observer.packageDeleted(packageName, returnCode);
9221                     } catch (RemoteException e) {
9222                         Log.i(TAG, "Observer no longer exists.");
9223                     } //end catch
9224                 } //end if
9225             } //end run
9226         });
9227     }
9228 
isPackageDeviceAdmin(String packageName, int userId)9229     private boolean isPackageDeviceAdmin(String packageName, int userId) {
9230         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
9231                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
9232         try {
9233             if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId)
9234                     || dpm.isDeviceOwner(packageName))) {
9235                 return true;
9236             }
9237         } catch (RemoteException e) {
9238         }
9239         return false;
9240     }
9241 
9242     /**
9243      *  This method is an internal method that could be get invoked either
9244      *  to delete an installed package or to clean up a failed installation.
9245      *  After deleting an installed package, a broadcast is sent to notify any
9246      *  listeners that the package has been installed. For cleaning up a failed
9247      *  installation, the broadcast is not necessary since the package's
9248      *  installation wouldn't have sent the initial broadcast either
9249      *  The key steps in deleting a package are
9250      *  deleting the package information in internal structures like mPackages,
9251      *  deleting the packages base directories through installd
9252      *  updating mSettings to reflect current status
9253      *  persisting settings for later use
9254      *  sending a broadcast if necessary
9255      */
deletePackageX(String packageName, int userId, int flags)9256     private int deletePackageX(String packageName, int userId, int flags) {
9257         final PackageRemovedInfo info = new PackageRemovedInfo();
9258         final boolean res;
9259 
9260         if (isPackageDeviceAdmin(packageName, userId)) {
9261             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
9262             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
9263         }
9264 
9265         boolean removedForAllUsers = false;
9266         boolean systemUpdate = false;
9267 
9268         // for the uninstall-updates case and restricted profiles, remember the per-
9269         // userhandle installed state
9270         int[] allUsers;
9271         boolean[] perUserInstalled;
9272         synchronized (mPackages) {
9273             PackageSetting ps = mSettings.mPackages.get(packageName);
9274             allUsers = sUserManager.getUserIds();
9275             perUserInstalled = new boolean[allUsers.length];
9276             for (int i = 0; i < allUsers.length; i++) {
9277                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
9278             }
9279         }
9280 
9281         synchronized (mInstallLock) {
9282             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
9283             res = deletePackageLI(packageName,
9284                     (flags & PackageManager.DELETE_ALL_USERS) != 0
9285                             ? UserHandle.ALL : new UserHandle(userId),
9286                     true, allUsers, perUserInstalled,
9287                     flags | REMOVE_CHATTY, info, true);
9288             systemUpdate = info.isRemovedPackageSystemUpdate;
9289             if (res && !systemUpdate && mPackages.get(packageName) == null) {
9290                 removedForAllUsers = true;
9291             }
9292             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
9293                     + " removedForAllUsers=" + removedForAllUsers);
9294         }
9295 
9296         if (res) {
9297             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
9298 
9299             // If the removed package was a system update, the old system package
9300             // was re-enabled; we need to broadcast this information
9301             if (systemUpdate) {
9302                 Bundle extras = new Bundle(1);
9303                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
9304                         ? info.removedAppId : info.uid);
9305                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
9306 
9307                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
9308                         extras, null, null, null);
9309                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
9310                         extras, null, null, null);
9311                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
9312                         null, packageName, null, null);
9313             }
9314         }
9315         // Force a gc here.
9316         Runtime.getRuntime().gc();
9317         // Delete the resources here after sending the broadcast to let
9318         // other processes clean up before deleting resources.
9319         if (info.args != null) {
9320             synchronized (mInstallLock) {
9321                 info.args.doPostDeleteLI(true);
9322             }
9323         }
9324 
9325         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
9326     }
9327 
9328     static class PackageRemovedInfo {
9329         String removedPackage;
9330         int uid = -1;
9331         int removedAppId = -1;
9332         int[] removedUsers = null;
9333         boolean isRemovedPackageSystemUpdate = false;
9334         // Clean up resources deleted packages.
9335         InstallArgs args = null;
9336 
sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers)9337         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
9338             Bundle extras = new Bundle(1);
9339             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
9340             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
9341             if (replacing) {
9342                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
9343             }
9344             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
9345             if (removedPackage != null) {
9346                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
9347                         extras, null, null, removedUsers);
9348                 if (fullRemove && !replacing) {
9349                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
9350                             extras, null, null, removedUsers);
9351                 }
9352             }
9353             if (removedAppId >= 0) {
9354                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
9355                         removedUsers);
9356             }
9357         }
9358     }
9359 
9360     /*
9361      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
9362      * flag is not set, the data directory is removed as well.
9363      * make sure this flag is set for partially installed apps. If not its meaningless to
9364      * delete a partially installed application.
9365      */
removePackageDataLI(PackageSetting ps, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, int flags, boolean writeSettings)9366     private void removePackageDataLI(PackageSetting ps,
9367             int[] allUserHandles, boolean[] perUserInstalled,
9368             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
9369         String packageName = ps.name;
9370         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
9371         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
9372         // Retrieve object to delete permissions for shared user later on
9373         final PackageSetting deletedPs;
9374         // reader
9375         synchronized (mPackages) {
9376             deletedPs = mSettings.mPackages.get(packageName);
9377             if (outInfo != null) {
9378                 outInfo.removedPackage = packageName;
9379                 outInfo.removedUsers = deletedPs != null
9380                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
9381                         : null;
9382             }
9383         }
9384         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
9385             removeDataDirsLI(packageName);
9386             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
9387         }
9388         // writer
9389         synchronized (mPackages) {
9390             if (deletedPs != null) {
9391                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
9392                     if (outInfo != null) {
9393                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
9394                     }
9395                     if (deletedPs != null) {
9396                         updatePermissionsLPw(deletedPs.name, null, 0);
9397                         if (deletedPs.sharedUser != null) {
9398                             // remove permissions associated with package
9399                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
9400                         }
9401                     }
9402                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
9403                 }
9404                 // make sure to preserve per-user disabled state if this removal was just
9405                 // a downgrade of a system app to the factory package
9406                 if (allUserHandles != null && perUserInstalled != null) {
9407                     if (DEBUG_REMOVE) {
9408                         Slog.d(TAG, "Propagating install state across downgrade");
9409                     }
9410                     for (int i = 0; i < allUserHandles.length; i++) {
9411                         if (DEBUG_REMOVE) {
9412                             Slog.d(TAG, "    user " + allUserHandles[i]
9413                                     + " => " + perUserInstalled[i]);
9414                         }
9415                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
9416                     }
9417                 }
9418             }
9419             // can downgrade to reader
9420             if (writeSettings) {
9421                 // Save settings now
9422                 mSettings.writeLPr();
9423             }
9424         }
9425         if (outInfo != null) {
9426             // A user ID was deleted here. Go through all users and remove it
9427             // from KeyStore.
9428             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
9429         }
9430     }
9431 
locationIsPrivileged(File path)9432     static boolean locationIsPrivileged(File path) {
9433         try {
9434             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
9435                     .getCanonicalPath();
9436             return path.getCanonicalPath().startsWith(privilegedAppDir);
9437         } catch (IOException e) {
9438             Slog.e(TAG, "Unable to access code path " + path);
9439         }
9440         return false;
9441     }
9442 
9443     /*
9444      * Tries to delete system package.
9445      */
deleteSystemPackageLI(PackageSetting newPs, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)9446     private boolean deleteSystemPackageLI(PackageSetting newPs,
9447             int[] allUserHandles, boolean[] perUserInstalled,
9448             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
9449         final boolean applyUserRestrictions
9450                 = (allUserHandles != null) && (perUserInstalled != null);
9451         PackageSetting disabledPs = null;
9452         // Confirm if the system package has been updated
9453         // An updated system app can be deleted. This will also have to restore
9454         // the system pkg from system partition
9455         // reader
9456         synchronized (mPackages) {
9457             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
9458         }
9459         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
9460                 + " disabledPs=" + disabledPs);
9461         if (disabledPs == null) {
9462             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
9463             return false;
9464         } else if (DEBUG_REMOVE) {
9465             Slog.d(TAG, "Deleting system pkg from data partition");
9466         }
9467         if (DEBUG_REMOVE) {
9468             if (applyUserRestrictions) {
9469                 Slog.d(TAG, "Remembering install states:");
9470                 for (int i = 0; i < allUserHandles.length; i++) {
9471                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
9472                 }
9473             }
9474         }
9475         // Delete the updated package
9476         outInfo.isRemovedPackageSystemUpdate = true;
9477         if (disabledPs.versionCode < newPs.versionCode) {
9478             // Delete data for downgrades
9479             flags &= ~PackageManager.DELETE_KEEP_DATA;
9480         } else {
9481             // Preserve data by setting flag
9482             flags |= PackageManager.DELETE_KEEP_DATA;
9483         }
9484         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
9485                 allUserHandles, perUserInstalled, outInfo, writeSettings);
9486         if (!ret) {
9487             return false;
9488         }
9489         // writer
9490         synchronized (mPackages) {
9491             // Reinstate the old system package
9492             mSettings.enableSystemPackageLPw(newPs.name);
9493             // Remove any native libraries from the upgraded package.
9494             NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString);
9495         }
9496         // Install the system package
9497         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
9498         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
9499         if (locationIsPrivileged(disabledPs.codePath)) {
9500             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9501         }
9502         PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath,
9503                 parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
9504 
9505         if (newPkg == null) {
9506             Slog.w(TAG, "Failed to restore system package:" + newPs.name
9507                     + " with error:" + mLastScanError);
9508             return false;
9509         }
9510         // writer
9511         synchronized (mPackages) {
9512             updatePermissionsLPw(newPkg.packageName, newPkg,
9513                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
9514             if (applyUserRestrictions) {
9515                 if (DEBUG_REMOVE) {
9516                     Slog.d(TAG, "Propagating install state across reinstall");
9517                 }
9518                 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
9519                 for (int i = 0; i < allUserHandles.length; i++) {
9520                     if (DEBUG_REMOVE) {
9521                         Slog.d(TAG, "    user " + allUserHandles[i]
9522                                 + " => " + perUserInstalled[i]);
9523                     }
9524                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
9525                 }
9526                 // Regardless of writeSettings we need to ensure that this restriction
9527                 // state propagation is persisted
9528                 mSettings.writeAllUsersPackageRestrictionsLPr();
9529             }
9530             // can downgrade to reader here
9531             if (writeSettings) {
9532                 mSettings.writeLPr();
9533             }
9534         }
9535         return true;
9536     }
9537 
deleteInstalledPackageLI(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, boolean writeSettings)9538     private boolean deleteInstalledPackageLI(PackageSetting ps,
9539             boolean deleteCodeAndResources, int flags,
9540             int[] allUserHandles, boolean[] perUserInstalled,
9541             PackageRemovedInfo outInfo, boolean writeSettings) {
9542         if (outInfo != null) {
9543             outInfo.uid = ps.appId;
9544         }
9545 
9546         // Delete package data from internal structures and also remove data if flag is set
9547         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
9548 
9549         // Delete application code and resources
9550         if (deleteCodeAndResources && (outInfo != null)) {
9551             outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
9552                     ps.resourcePathString, ps.nativeLibraryPathString);
9553         }
9554         return true;
9555     }
9556 
9557     /*
9558      * This method handles package deletion in general
9559      */
deletePackageLI(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)9560     private boolean deletePackageLI(String packageName, UserHandle user,
9561             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
9562             int flags, PackageRemovedInfo outInfo,
9563             boolean writeSettings) {
9564         if (packageName == null) {
9565             Slog.w(TAG, "Attempt to delete null packageName.");
9566             return false;
9567         }
9568         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
9569         PackageSetting ps;
9570         boolean dataOnly = false;
9571         int removeUser = -1;
9572         int appId = -1;
9573         synchronized (mPackages) {
9574             ps = mSettings.mPackages.get(packageName);
9575             if (ps == null) {
9576                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9577                 return false;
9578             }
9579             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
9580                     && user.getIdentifier() != UserHandle.USER_ALL) {
9581                 // The caller is asking that the package only be deleted for a single
9582                 // user.  To do this, we just mark its uninstalled state and delete
9583                 // its data.  If this is a system app, we only allow this to happen if
9584                 // they have set the special DELETE_SYSTEM_APP which requests different
9585                 // semantics than normal for uninstalling system apps.
9586                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
9587                 ps.setUserState(user.getIdentifier(),
9588                         COMPONENT_ENABLED_STATE_DEFAULT,
9589                         false, //installed
9590                         true,  //stopped
9591                         true,  //notLaunched
9592                         false, //blocked
9593                         null, null, null);
9594                 if (!isSystemApp(ps)) {
9595                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
9596                         // Other user still have this package installed, so all
9597                         // we need to do is clear this user's data and save that
9598                         // it is uninstalled.
9599                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
9600                         removeUser = user.getIdentifier();
9601                         appId = ps.appId;
9602                         mSettings.writePackageRestrictionsLPr(removeUser);
9603                     } else {
9604                         // We need to set it back to 'installed' so the uninstall
9605                         // broadcasts will be sent correctly.
9606                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
9607                         ps.setInstalled(true, user.getIdentifier());
9608                     }
9609                 } else {
9610                     // This is a system app, so we assume that the
9611                     // other users still have this package installed, so all
9612                     // we need to do is clear this user's data and save that
9613                     // it is uninstalled.
9614                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
9615                     removeUser = user.getIdentifier();
9616                     appId = ps.appId;
9617                     mSettings.writePackageRestrictionsLPr(removeUser);
9618                 }
9619             }
9620         }
9621 
9622         if (removeUser >= 0) {
9623             // From above, we determined that we are deleting this only
9624             // for a single user.  Continue the work here.
9625             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
9626             if (outInfo != null) {
9627                 outInfo.removedPackage = packageName;
9628                 outInfo.removedAppId = appId;
9629                 outInfo.removedUsers = new int[] {removeUser};
9630             }
9631             mInstaller.clearUserData(packageName, removeUser);
9632             removeKeystoreDataIfNeeded(removeUser, appId);
9633             schedulePackageCleaning(packageName, removeUser, false);
9634             return true;
9635         }
9636 
9637         if (dataOnly) {
9638             // Delete application data first
9639             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
9640             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
9641             return true;
9642         }
9643 
9644         boolean ret = false;
9645         mSettings.mKeySetManager.removeAppKeySetData(packageName);
9646         if (isSystemApp(ps)) {
9647             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
9648             // When an updated system application is deleted we delete the existing resources as well and
9649             // fall back to existing code in system partition
9650             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
9651                     flags, outInfo, writeSettings);
9652         } else {
9653             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
9654             // Kill application pre-emptively especially for apps on sd.
9655             killApplication(packageName, ps.appId, "uninstall pkg");
9656             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
9657                     allUserHandles, perUserInstalled,
9658                     outInfo, writeSettings);
9659         }
9660 
9661         return ret;
9662     }
9663 
9664     private final class ClearStorageConnection implements ServiceConnection {
9665         IMediaContainerService mContainerService;
9666 
9667         @Override
onServiceConnected(ComponentName name, IBinder service)9668         public void onServiceConnected(ComponentName name, IBinder service) {
9669             synchronized (this) {
9670                 mContainerService = IMediaContainerService.Stub.asInterface(service);
9671                 notifyAll();
9672             }
9673         }
9674 
9675         @Override
onServiceDisconnected(ComponentName name)9676         public void onServiceDisconnected(ComponentName name) {
9677         }
9678     }
9679 
clearExternalStorageDataSync(String packageName, int userId, boolean allData)9680     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
9681         final boolean mounted;
9682         if (Environment.isExternalStorageEmulated()) {
9683             mounted = true;
9684         } else {
9685             final String status = Environment.getExternalStorageState();
9686 
9687             mounted = status.equals(Environment.MEDIA_MOUNTED)
9688                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
9689         }
9690 
9691         if (!mounted) {
9692             return;
9693         }
9694 
9695         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
9696         int[] users;
9697         if (userId == UserHandle.USER_ALL) {
9698             users = sUserManager.getUserIds();
9699         } else {
9700             users = new int[] { userId };
9701         }
9702         final ClearStorageConnection conn = new ClearStorageConnection();
9703         if (mContext.bindServiceAsUser(
9704                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
9705             try {
9706                 for (int curUser : users) {
9707                     long timeout = SystemClock.uptimeMillis() + 5000;
9708                     synchronized (conn) {
9709                         long now = SystemClock.uptimeMillis();
9710                         while (conn.mContainerService == null && now < timeout) {
9711                             try {
9712                                 conn.wait(timeout - now);
9713                             } catch (InterruptedException e) {
9714                             }
9715                         }
9716                     }
9717                     if (conn.mContainerService == null) {
9718                         return;
9719                     }
9720 
9721                     final UserEnvironment userEnv = new UserEnvironment(curUser);
9722                     clearDirectory(conn.mContainerService,
9723                             userEnv.buildExternalStorageAppCacheDirs(packageName));
9724                     if (allData) {
9725                         clearDirectory(conn.mContainerService,
9726                                 userEnv.buildExternalStorageAppDataDirs(packageName));
9727                         clearDirectory(conn.mContainerService,
9728                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
9729                     }
9730                 }
9731             } finally {
9732                 mContext.unbindService(conn);
9733             }
9734         }
9735     }
9736 
9737     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)9738     public void clearApplicationUserData(final String packageName,
9739             final IPackageDataObserver observer, final int userId) {
9740         mContext.enforceCallingOrSelfPermission(
9741                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
9742         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
9743         // Queue up an async operation since the package deletion may take a little while.
9744         mHandler.post(new Runnable() {
9745             public void run() {
9746                 mHandler.removeCallbacks(this);
9747                 final boolean succeeded;
9748                 synchronized (mInstallLock) {
9749                     succeeded = clearApplicationUserDataLI(packageName, userId);
9750                 }
9751                 clearExternalStorageDataSync(packageName, userId, true);
9752                 if (succeeded) {
9753                     // invoke DeviceStorageMonitor's update method to clear any notifications
9754                     DeviceStorageMonitorService dsm = (DeviceStorageMonitorService)
9755                             ServiceManager.getService(DeviceStorageMonitorService.SERVICE);
9756                     if (dsm != null) {
9757                         dsm.updateMemory();
9758                     }
9759                 }
9760                 if(observer != null) {
9761                     try {
9762                         observer.onRemoveCompleted(packageName, succeeded);
9763                     } catch (RemoteException e) {
9764                         Log.i(TAG, "Observer no longer exists.");
9765                     }
9766                 } //end if observer
9767             } //end run
9768         });
9769     }
9770 
clearApplicationUserDataLI(String packageName, int userId)9771     private boolean clearApplicationUserDataLI(String packageName, int userId) {
9772         if (packageName == null) {
9773             Slog.w(TAG, "Attempt to delete null packageName.");
9774             return false;
9775         }
9776         PackageParser.Package p;
9777         boolean dataOnly = false;
9778         final int appId;
9779         synchronized (mPackages) {
9780             p = mPackages.get(packageName);
9781             if (p == null) {
9782                 dataOnly = true;
9783                 PackageSetting ps = mSettings.mPackages.get(packageName);
9784                 if ((ps == null) || (ps.pkg == null)) {
9785                     Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9786                     return false;
9787                 }
9788                 p = ps.pkg;
9789             }
9790             if (!dataOnly) {
9791                 // need to check this only for fully installed applications
9792                 if (p == null) {
9793                     Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9794                     return false;
9795                 }
9796                 final ApplicationInfo applicationInfo = p.applicationInfo;
9797                 if (applicationInfo == null) {
9798                     Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9799                     return false;
9800                 }
9801             }
9802             if (p != null && p.applicationInfo != null) {
9803                 appId = p.applicationInfo.uid;
9804             } else {
9805                 appId = -1;
9806             }
9807         }
9808         int retCode = mInstaller.clearUserData(packageName, userId);
9809         if (retCode < 0) {
9810             Slog.w(TAG, "Couldn't remove cache files for package: "
9811                     + packageName);
9812             return false;
9813         }
9814         removeKeystoreDataIfNeeded(userId, appId);
9815         return true;
9816     }
9817 
9818     /**
9819      * Remove entries from the keystore daemon. Will only remove it if the
9820      * {@code appId} is valid.
9821      */
removeKeystoreDataIfNeeded(int userId, int appId)9822     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
9823         if (appId < 0) {
9824             return;
9825         }
9826 
9827         final KeyStore keyStore = KeyStore.getInstance();
9828         if (keyStore != null) {
9829             if (userId == UserHandle.USER_ALL) {
9830                 for (final int individual : sUserManager.getUserIds()) {
9831                     keyStore.clearUid(UserHandle.getUid(individual, appId));
9832                 }
9833             } else {
9834                 keyStore.clearUid(UserHandle.getUid(userId, appId));
9835             }
9836         } else {
9837             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
9838         }
9839     }
9840 
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)9841     public void deleteApplicationCacheFiles(final String packageName,
9842             final IPackageDataObserver observer) {
9843         mContext.enforceCallingOrSelfPermission(
9844                 android.Manifest.permission.DELETE_CACHE_FILES, null);
9845         // Queue up an async operation since the package deletion may take a little while.
9846         final int userId = UserHandle.getCallingUserId();
9847         mHandler.post(new Runnable() {
9848             public void run() {
9849                 mHandler.removeCallbacks(this);
9850                 final boolean succeded;
9851                 synchronized (mInstallLock) {
9852                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
9853                 }
9854                 clearExternalStorageDataSync(packageName, userId, false);
9855                 if(observer != null) {
9856                     try {
9857                         observer.onRemoveCompleted(packageName, succeded);
9858                     } catch (RemoteException e) {
9859                         Log.i(TAG, "Observer no longer exists.");
9860                     }
9861                 } //end if observer
9862             } //end run
9863         });
9864     }
9865 
deleteApplicationCacheFilesLI(String packageName, int userId)9866     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
9867         if (packageName == null) {
9868             Slog.w(TAG, "Attempt to delete null packageName.");
9869             return false;
9870         }
9871         PackageParser.Package p;
9872         synchronized (mPackages) {
9873             p = mPackages.get(packageName);
9874         }
9875         if (p == null) {
9876             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
9877             return false;
9878         }
9879         final ApplicationInfo applicationInfo = p.applicationInfo;
9880         if (applicationInfo == null) {
9881             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9882             return false;
9883         }
9884         int retCode = mInstaller.deleteCacheFiles(packageName, userId);
9885         if (retCode < 0) {
9886             Slog.w(TAG, "Couldn't remove cache files for package: "
9887                        + packageName + " u" + userId);
9888             return false;
9889         }
9890         return true;
9891     }
9892 
getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)9893     public void getPackageSizeInfo(final String packageName, int userHandle,
9894             final IPackageStatsObserver observer) {
9895         mContext.enforceCallingOrSelfPermission(
9896                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
9897 
9898         PackageStats stats = new PackageStats(packageName, userHandle);
9899 
9900         /*
9901          * Queue up an async operation since the package measurement may take a
9902          * little while.
9903          */
9904         Message msg = mHandler.obtainMessage(INIT_COPY);
9905         msg.obj = new MeasureParams(stats, observer);
9906         mHandler.sendMessage(msg);
9907     }
9908 
getPackageSizeInfoLI(String packageName, int userHandle, PackageStats pStats)9909     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
9910             PackageStats pStats) {
9911         if (packageName == null) {
9912             Slog.w(TAG, "Attempt to get size of null packageName.");
9913             return false;
9914         }
9915         PackageParser.Package p;
9916         boolean dataOnly = false;
9917         String libDirPath = null;
9918         String asecPath = null;
9919         synchronized (mPackages) {
9920             p = mPackages.get(packageName);
9921             PackageSetting ps = mSettings.mPackages.get(packageName);
9922             if(p == null) {
9923                 dataOnly = true;
9924                 if((ps == null) || (ps.pkg == null)) {
9925                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
9926                     return false;
9927                 }
9928                 p = ps.pkg;
9929             }
9930             if (ps != null) {
9931                 libDirPath = ps.nativeLibraryPathString;
9932             }
9933             if (p != null && (isExternal(p) || isForwardLocked(p))) {
9934                 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir);
9935                 if (secureContainerId != null) {
9936                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
9937                 }
9938             }
9939         }
9940         String publicSrcDir = null;
9941         if(!dataOnly) {
9942             final ApplicationInfo applicationInfo = p.applicationInfo;
9943             if (applicationInfo == null) {
9944                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9945                 return false;
9946             }
9947             if (isForwardLocked(p)) {
9948                 publicSrcDir = applicationInfo.publicSourceDir;
9949             }
9950         }
9951         int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath,
9952                 publicSrcDir, asecPath, pStats);
9953         if (res < 0) {
9954             return false;
9955         }
9956 
9957         // Fix-up for forward-locked applications in ASEC containers.
9958         if (!isExternal(p)) {
9959             pStats.codeSize += pStats.externalCodeSize;
9960             pStats.externalCodeSize = 0L;
9961         }
9962 
9963         return true;
9964     }
9965 
9966 
addPackageToPreferred(String packageName)9967     public void addPackageToPreferred(String packageName) {
9968         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
9969     }
9970 
removePackageFromPreferred(String packageName)9971     public void removePackageFromPreferred(String packageName) {
9972         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
9973     }
9974 
getPreferredPackages(int flags)9975     public List<PackageInfo> getPreferredPackages(int flags) {
9976         return new ArrayList<PackageInfo>();
9977     }
9978 
getUidTargetSdkVersionLockedLPr(int uid)9979     private int getUidTargetSdkVersionLockedLPr(int uid) {
9980         Object obj = mSettings.getUserIdLPr(uid);
9981         if (obj instanceof SharedUserSetting) {
9982             final SharedUserSetting sus = (SharedUserSetting) obj;
9983             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
9984             final Iterator<PackageSetting> it = sus.packages.iterator();
9985             while (it.hasNext()) {
9986                 final PackageSetting ps = it.next();
9987                 if (ps.pkg != null) {
9988                     int v = ps.pkg.applicationInfo.targetSdkVersion;
9989                     if (v < vers) vers = v;
9990                 }
9991             }
9992             return vers;
9993         } else if (obj instanceof PackageSetting) {
9994             final PackageSetting ps = (PackageSetting) obj;
9995             if (ps.pkg != null) {
9996                 return ps.pkg.applicationInfo.targetSdkVersion;
9997             }
9998         }
9999         return Build.VERSION_CODES.CUR_DEVELOPMENT;
10000     }
10001 
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)10002     public void addPreferredActivity(IntentFilter filter, int match,
10003             ComponentName[] set, ComponentName activity, int userId) {
10004         addPreferredActivityInternal(filter, match, set, activity, true, userId);
10005     }
10006 
addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId)10007     private void addPreferredActivityInternal(IntentFilter filter, int match,
10008             ComponentName[] set, ComponentName activity, boolean always, int userId) {
10009         // writer
10010         int callingUid = Binder.getCallingUid();
10011         enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
10012         if (filter.countActions() == 0) {
10013             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
10014             return;
10015         }
10016         synchronized (mPackages) {
10017             if (mContext.checkCallingOrSelfPermission(
10018                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
10019                     != PackageManager.PERMISSION_GRANTED) {
10020                 if (getUidTargetSdkVersionLockedLPr(callingUid)
10021                         < Build.VERSION_CODES.FROYO) {
10022                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
10023                             + callingUid);
10024                     return;
10025                 }
10026                 mContext.enforceCallingOrSelfPermission(
10027                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10028             }
10029 
10030             Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
10031             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
10032             mSettings.editPreferredActivitiesLPw(userId).addFilter(
10033                     new PreferredActivity(filter, match, set, activity, always));
10034             mSettings.writePackageRestrictionsLPr(userId);
10035         }
10036     }
10037 
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)10038     public void replacePreferredActivity(IntentFilter filter, int match,
10039             ComponentName[] set, ComponentName activity) {
10040         if (filter.countActions() != 1) {
10041             throw new IllegalArgumentException(
10042                     "replacePreferredActivity expects filter to have only 1 action.");
10043         }
10044         if (filter.countDataAuthorities() != 0
10045                 || filter.countDataPaths() != 0
10046                 || filter.countDataSchemes() > 1
10047                 || filter.countDataTypes() != 0) {
10048             throw new IllegalArgumentException(
10049                     "replacePreferredActivity expects filter to have no data authorities, " +
10050                     "paths, or types; and at most one scheme.");
10051         }
10052         synchronized (mPackages) {
10053             if (mContext.checkCallingOrSelfPermission(
10054                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
10055                     != PackageManager.PERMISSION_GRANTED) {
10056                 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
10057                         < Build.VERSION_CODES.FROYO) {
10058                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
10059                             + Binder.getCallingUid());
10060                     return;
10061                 }
10062                 mContext.enforceCallingOrSelfPermission(
10063                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10064             }
10065 
10066             final int callingUserId = UserHandle.getCallingUserId();
10067             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
10068             if (pir != null) {
10069                 Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0));
10070                 if (filter.countDataSchemes() == 1) {
10071                     Uri.Builder builder = new Uri.Builder();
10072                     builder.scheme(filter.getDataScheme(0));
10073                     intent.setData(builder.build());
10074                 }
10075                 List<PreferredActivity> matches = pir.queryIntent(
10076                         intent, null, true, callingUserId);
10077                 if (DEBUG_PREFERRED) {
10078                     Slog.i(TAG, matches.size() + " preferred matches for " + intent);
10079                 }
10080                 for (int i = 0; i < matches.size(); i++) {
10081                     PreferredActivity pa = matches.get(i);
10082                     if (DEBUG_PREFERRED) {
10083                         Slog.i(TAG, "Removing preferred activity "
10084                                 + pa.mPref.mComponent + ":");
10085                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
10086                     }
10087                     pir.removeFilter(pa);
10088                 }
10089             }
10090             addPreferredActivityInternal(filter, match, set, activity, true, callingUserId);
10091         }
10092     }
10093 
clearPackagePreferredActivities(String packageName)10094     public void clearPackagePreferredActivities(String packageName) {
10095         final int uid = Binder.getCallingUid();
10096         // writer
10097         synchronized (mPackages) {
10098             PackageParser.Package pkg = mPackages.get(packageName);
10099             if (pkg == null || pkg.applicationInfo.uid != uid) {
10100                 if (mContext.checkCallingOrSelfPermission(
10101                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
10102                         != PackageManager.PERMISSION_GRANTED) {
10103                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
10104                             < Build.VERSION_CODES.FROYO) {
10105                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
10106                                 + Binder.getCallingUid());
10107                         return;
10108                     }
10109                     mContext.enforceCallingOrSelfPermission(
10110                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10111                 }
10112             }
10113 
10114             int user = UserHandle.getCallingUserId();
10115             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
10116                 mSettings.writePackageRestrictionsLPr(user);
10117                 scheduleWriteSettingsLocked();
10118             }
10119         }
10120     }
10121 
10122     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearPackagePreferredActivitiesLPw(String packageName, int userId)10123     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
10124         ArrayList<PreferredActivity> removed = null;
10125         boolean changed = false;
10126         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
10127             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
10128             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
10129             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
10130                 continue;
10131             }
10132             Iterator<PreferredActivity> it = pir.filterIterator();
10133             while (it.hasNext()) {
10134                 PreferredActivity pa = it.next();
10135                 // Mark entry for removal only if it matches the package name
10136                 // and the entry is of type "always".
10137                 if (packageName == null ||
10138                         (pa.mPref.mComponent.getPackageName().equals(packageName)
10139                                 && pa.mPref.mAlways)) {
10140                     if (removed == null) {
10141                         removed = new ArrayList<PreferredActivity>();
10142                     }
10143                     removed.add(pa);
10144                 }
10145             }
10146             if (removed != null) {
10147                 for (int j=0; j<removed.size(); j++) {
10148                     PreferredActivity pa = removed.get(j);
10149                     pir.removeFilter(pa);
10150                 }
10151                 changed = true;
10152             }
10153         }
10154         return changed;
10155     }
10156 
resetPreferredActivities(int userId)10157     public void resetPreferredActivities(int userId) {
10158         mContext.enforceCallingOrSelfPermission(
10159                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10160         // writer
10161         synchronized (mPackages) {
10162             int user = UserHandle.getCallingUserId();
10163             clearPackagePreferredActivitiesLPw(null, user);
10164             mSettings.readDefaultPreferredAppsLPw(this, user);
10165             mSettings.writePackageRestrictionsLPr(user);
10166             scheduleWriteSettingsLocked();
10167         }
10168     }
10169 
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)10170     public int getPreferredActivities(List<IntentFilter> outFilters,
10171             List<ComponentName> outActivities, String packageName) {
10172 
10173         int num = 0;
10174         final int userId = UserHandle.getCallingUserId();
10175         // reader
10176         synchronized (mPackages) {
10177             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
10178             if (pir != null) {
10179                 final Iterator<PreferredActivity> it = pir.filterIterator();
10180                 while (it.hasNext()) {
10181                     final PreferredActivity pa = it.next();
10182                     if (packageName == null
10183                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
10184                                     && pa.mPref.mAlways)) {
10185                         if (outFilters != null) {
10186                             outFilters.add(new IntentFilter(pa));
10187                         }
10188                         if (outActivities != null) {
10189                             outActivities.add(pa.mPref.mComponent);
10190                         }
10191                     }
10192                 }
10193             }
10194         }
10195 
10196         return num;
10197     }
10198 
10199     @Override
getHomeActivities(List<ResolveInfo> allHomeCandidates)10200     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
10201         Intent intent = new Intent(Intent.ACTION_MAIN);
10202         intent.addCategory(Intent.CATEGORY_HOME);
10203 
10204         final int callingUserId = UserHandle.getCallingUserId();
10205         List<ResolveInfo> list = queryIntentActivities(intent, null,
10206                 PackageManager.GET_META_DATA, callingUserId);
10207         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
10208                 true, false, false, callingUserId);
10209 
10210         allHomeCandidates.clear();
10211         if (list != null) {
10212             for (ResolveInfo ri : list) {
10213                 allHomeCandidates.add(ri);
10214             }
10215         }
10216         return (preferred == null || preferred.activityInfo == null)
10217                 ? null
10218                 : new ComponentName(preferred.activityInfo.packageName,
10219                         preferred.activityInfo.name);
10220     }
10221 
10222     @Override
setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)10223     public void setApplicationEnabledSetting(String appPackageName,
10224             int newState, int flags, int userId, String callingPackage) {
10225         if (!sUserManager.exists(userId)) return;
10226         if (callingPackage == null) {
10227             callingPackage = Integer.toString(Binder.getCallingUid());
10228         }
10229         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
10230     }
10231 
10232     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)10233     public void setComponentEnabledSetting(ComponentName componentName,
10234             int newState, int flags, int userId) {
10235         if (!sUserManager.exists(userId)) return;
10236         setEnabledSetting(componentName.getPackageName(),
10237                 componentName.getClassName(), newState, flags, userId, null);
10238     }
10239 
setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)10240     private void setEnabledSetting(final String packageName, String className, int newState,
10241             final int flags, int userId, String callingPackage) {
10242         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
10243               || newState == COMPONENT_ENABLED_STATE_ENABLED
10244               || newState == COMPONENT_ENABLED_STATE_DISABLED
10245               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
10246               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
10247             throw new IllegalArgumentException("Invalid new component state: "
10248                     + newState);
10249         }
10250         PackageSetting pkgSetting;
10251         final int uid = Binder.getCallingUid();
10252         final int permission = mContext.checkCallingOrSelfPermission(
10253                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
10254         enforceCrossUserPermission(uid, userId, false, "set enabled");
10255         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
10256         boolean sendNow = false;
10257         boolean isApp = (className == null);
10258         String componentName = isApp ? packageName : className;
10259         int packageUid = -1;
10260         ArrayList<String> components;
10261 
10262         // writer
10263         synchronized (mPackages) {
10264             pkgSetting = mSettings.mPackages.get(packageName);
10265             if (pkgSetting == null) {
10266                 if (className == null) {
10267                     throw new IllegalArgumentException(
10268                             "Unknown package: " + packageName);
10269                 }
10270                 throw new IllegalArgumentException(
10271                         "Unknown component: " + packageName
10272                         + "/" + className);
10273             }
10274             // Allow root and verify that userId is not being specified by a different user
10275             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
10276                 throw new SecurityException(
10277                         "Permission Denial: attempt to change component state from pid="
10278                         + Binder.getCallingPid()
10279                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
10280             }
10281             if (className == null) {
10282                 // We're dealing with an application/package level state change
10283                 if (pkgSetting.getEnabled(userId) == newState) {
10284                     // Nothing to do
10285                     return;
10286                 }
10287                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
10288                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
10289                     // Don't care about who enables an app.
10290                     callingPackage = null;
10291                 }
10292                 pkgSetting.setEnabled(newState, userId, callingPackage);
10293                 // pkgSetting.pkg.mSetEnabled = newState;
10294             } else {
10295                 // We're dealing with a component level state change
10296                 // First, verify that this is a valid class name.
10297                 PackageParser.Package pkg = pkgSetting.pkg;
10298                 if (pkg == null || !pkg.hasComponentClassName(className)) {
10299                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
10300                         throw new IllegalArgumentException("Component class " + className
10301                                 + " does not exist in " + packageName);
10302                     } else {
10303                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
10304                                 + className + " does not exist in " + packageName);
10305                     }
10306                 }
10307                 switch (newState) {
10308                 case COMPONENT_ENABLED_STATE_ENABLED:
10309                     if (!pkgSetting.enableComponentLPw(className, userId)) {
10310                         return;
10311                     }
10312                     break;
10313                 case COMPONENT_ENABLED_STATE_DISABLED:
10314                     if (!pkgSetting.disableComponentLPw(className, userId)) {
10315                         return;
10316                     }
10317                     break;
10318                 case COMPONENT_ENABLED_STATE_DEFAULT:
10319                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
10320                         return;
10321                     }
10322                     break;
10323                 default:
10324                     Slog.e(TAG, "Invalid new component state: " + newState);
10325                     return;
10326                 }
10327             }
10328             mSettings.writePackageRestrictionsLPr(userId);
10329             components = mPendingBroadcasts.get(userId, packageName);
10330             final boolean newPackage = components == null;
10331             if (newPackage) {
10332                 components = new ArrayList<String>();
10333             }
10334             if (!components.contains(componentName)) {
10335                 components.add(componentName);
10336             }
10337             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
10338                 sendNow = true;
10339                 // Purge entry from pending broadcast list if another one exists already
10340                 // since we are sending one right away.
10341                 mPendingBroadcasts.remove(userId, packageName);
10342             } else {
10343                 if (newPackage) {
10344                     mPendingBroadcasts.put(userId, packageName, components);
10345                 }
10346                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
10347                     // Schedule a message
10348                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
10349                 }
10350             }
10351         }
10352 
10353         long callingId = Binder.clearCallingIdentity();
10354         try {
10355             if (sendNow) {
10356                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
10357                 sendPackageChangedBroadcast(packageName,
10358                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
10359             }
10360         } finally {
10361             Binder.restoreCallingIdentity(callingId);
10362         }
10363     }
10364 
sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)10365     private void sendPackageChangedBroadcast(String packageName,
10366             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
10367         if (DEBUG_INSTALL)
10368             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
10369                     + componentNames);
10370         Bundle extras = new Bundle(4);
10371         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
10372         String nameList[] = new String[componentNames.size()];
10373         componentNames.toArray(nameList);
10374         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
10375         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
10376         extras.putInt(Intent.EXTRA_UID, packageUid);
10377         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
10378                 new int[] {UserHandle.getUserId(packageUid)});
10379     }
10380 
setPackageStoppedState(String packageName, boolean stopped, int userId)10381     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
10382         if (!sUserManager.exists(userId)) return;
10383         final int uid = Binder.getCallingUid();
10384         final int permission = mContext.checkCallingOrSelfPermission(
10385                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
10386         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
10387         enforceCrossUserPermission(uid, userId, true, "stop package");
10388         // writer
10389         synchronized (mPackages) {
10390             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
10391                     uid, userId)) {
10392                 scheduleWritePackageRestrictionsLocked(userId);
10393             }
10394         }
10395     }
10396 
getInstallerPackageName(String packageName)10397     public String getInstallerPackageName(String packageName) {
10398         // reader
10399         synchronized (mPackages) {
10400             return mSettings.getInstallerPackageNameLPr(packageName);
10401         }
10402     }
10403 
10404     @Override
getApplicationEnabledSetting(String packageName, int userId)10405     public int getApplicationEnabledSetting(String packageName, int userId) {
10406         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
10407         int uid = Binder.getCallingUid();
10408         enforceCrossUserPermission(uid, userId, false, "get enabled");
10409         // reader
10410         synchronized (mPackages) {
10411             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
10412         }
10413     }
10414 
10415     @Override
getComponentEnabledSetting(ComponentName componentName, int userId)10416     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
10417         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
10418         int uid = Binder.getCallingUid();
10419         enforceCrossUserPermission(uid, userId, false, "get component enabled");
10420         // reader
10421         synchronized (mPackages) {
10422             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
10423         }
10424     }
10425 
enterSafeMode()10426     public void enterSafeMode() {
10427         enforceSystemOrRoot("Only the system can request entering safe mode");
10428 
10429         if (!mSystemReady) {
10430             mSafeMode = true;
10431         }
10432     }
10433 
systemReady()10434     public void systemReady() {
10435         mSystemReady = true;
10436 
10437         // Read the compatibilty setting when the system is ready.
10438         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
10439                 mContext.getContentResolver(),
10440                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
10441         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
10442         if (DEBUG_SETTINGS) {
10443             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
10444         }
10445 
10446         synchronized (mPackages) {
10447             // Verify that all of the preferred activity components actually
10448             // exist.  It is possible for applications to be updated and at
10449             // that point remove a previously declared activity component that
10450             // had been set as a preferred activity.  We try to clean this up
10451             // the next time we encounter that preferred activity, but it is
10452             // possible for the user flow to never be able to return to that
10453             // situation so here we do a sanity check to make sure we haven't
10454             // left any junk around.
10455             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
10456             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
10457                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
10458                 removed.clear();
10459                 for (PreferredActivity pa : pir.filterSet()) {
10460                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
10461                         removed.add(pa);
10462                     }
10463                 }
10464                 if (removed.size() > 0) {
10465                     for (int j=0; j<removed.size(); j++) {
10466                         PreferredActivity pa = removed.get(i);
10467                         Slog.w(TAG, "Removing dangling preferred activity: "
10468                                 + pa.mPref.mComponent);
10469                         pir.removeFilter(pa);
10470                     }
10471                     mSettings.writePackageRestrictionsLPr(
10472                             mSettings.mPreferredActivities.keyAt(i));
10473                 }
10474             }
10475         }
10476         sUserManager.systemReady();
10477     }
10478 
isSafeMode()10479     public boolean isSafeMode() {
10480         return mSafeMode;
10481     }
10482 
hasSystemUidErrors()10483     public boolean hasSystemUidErrors() {
10484         return mHasSystemUidErrors;
10485     }
10486 
arrayToString(int[] array)10487     static String arrayToString(int[] array) {
10488         StringBuffer buf = new StringBuffer(128);
10489         buf.append('[');
10490         if (array != null) {
10491             for (int i=0; i<array.length; i++) {
10492                 if (i > 0) buf.append(", ");
10493                 buf.append(array[i]);
10494             }
10495         }
10496         buf.append(']');
10497         return buf.toString();
10498     }
10499 
10500     static class DumpState {
10501         public static final int DUMP_LIBS = 1 << 0;
10502 
10503         public static final int DUMP_FEATURES = 1 << 1;
10504 
10505         public static final int DUMP_RESOLVERS = 1 << 2;
10506 
10507         public static final int DUMP_PERMISSIONS = 1 << 3;
10508 
10509         public static final int DUMP_PACKAGES = 1 << 4;
10510 
10511         public static final int DUMP_SHARED_USERS = 1 << 5;
10512 
10513         public static final int DUMP_MESSAGES = 1 << 6;
10514 
10515         public static final int DUMP_PROVIDERS = 1 << 7;
10516 
10517         public static final int DUMP_VERIFIERS = 1 << 8;
10518 
10519         public static final int DUMP_PREFERRED = 1 << 9;
10520 
10521         public static final int DUMP_PREFERRED_XML = 1 << 10;
10522 
10523         public static final int DUMP_KEYSETS = 1 << 11;
10524 
10525         public static final int OPTION_SHOW_FILTERS = 1 << 0;
10526 
10527         private int mTypes;
10528 
10529         private int mOptions;
10530 
10531         private boolean mTitlePrinted;
10532 
10533         private SharedUserSetting mSharedUser;
10534 
isDumping(int type)10535         public boolean isDumping(int type) {
10536             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
10537                 return true;
10538             }
10539 
10540             return (mTypes & type) != 0;
10541         }
10542 
setDump(int type)10543         public void setDump(int type) {
10544             mTypes |= type;
10545         }
10546 
isOptionEnabled(int option)10547         public boolean isOptionEnabled(int option) {
10548             return (mOptions & option) != 0;
10549         }
10550 
setOptionEnabled(int option)10551         public void setOptionEnabled(int option) {
10552             mOptions |= option;
10553         }
10554 
onTitlePrinted()10555         public boolean onTitlePrinted() {
10556             final boolean printed = mTitlePrinted;
10557             mTitlePrinted = true;
10558             return printed;
10559         }
10560 
getTitlePrinted()10561         public boolean getTitlePrinted() {
10562             return mTitlePrinted;
10563         }
10564 
setTitlePrinted(boolean enabled)10565         public void setTitlePrinted(boolean enabled) {
10566             mTitlePrinted = enabled;
10567         }
10568 
getSharedUser()10569         public SharedUserSetting getSharedUser() {
10570             return mSharedUser;
10571         }
10572 
setSharedUser(SharedUserSetting user)10573         public void setSharedUser(SharedUserSetting user) {
10574             mSharedUser = user;
10575         }
10576     }
10577 
10578     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)10579     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10580         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
10581                 != PackageManager.PERMISSION_GRANTED) {
10582             pw.println("Permission Denial: can't dump ActivityManager from from pid="
10583                     + Binder.getCallingPid()
10584                     + ", uid=" + Binder.getCallingUid()
10585                     + " without permission "
10586                     + android.Manifest.permission.DUMP);
10587             return;
10588         }
10589 
10590         DumpState dumpState = new DumpState();
10591         boolean fullPreferred = false;
10592         boolean checkin = false;
10593 
10594         String packageName = null;
10595 
10596         int opti = 0;
10597         while (opti < args.length) {
10598             String opt = args[opti];
10599             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10600                 break;
10601             }
10602             opti++;
10603             if ("-a".equals(opt)) {
10604                 // Right now we only know how to print all.
10605             } else if ("-h".equals(opt)) {
10606                 pw.println("Package manager dump options:");
10607                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
10608                 pw.println("    --checkin: dump for a checkin");
10609                 pw.println("    -f: print details of intent filters");
10610                 pw.println("    -h: print this help");
10611                 pw.println("  cmd may be one of:");
10612                 pw.println("    l[ibraries]: list known shared libraries");
10613                 pw.println("    f[ibraries]: list device features");
10614                 pw.println("    r[esolvers]: dump intent resolvers");
10615                 pw.println("    perm[issions]: dump permissions");
10616                 pw.println("    pref[erred]: print preferred package settings");
10617                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
10618                 pw.println("    prov[iders]: dump content providers");
10619                 pw.println("    p[ackages]: dump installed packages");
10620                 pw.println("    s[hared-users]: dump shared user IDs");
10621                 pw.println("    m[essages]: print collected runtime messages");
10622                 pw.println("    v[erifiers]: print package verifier info");
10623                 pw.println("    <package.name>: info about given package");
10624                 pw.println("    k[eysets]: print known keysets");
10625                 return;
10626             } else if ("--checkin".equals(opt)) {
10627                 checkin = true;
10628             } else if ("-f".equals(opt)) {
10629                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
10630             } else {
10631                 pw.println("Unknown argument: " + opt + "; use -h for help");
10632             }
10633         }
10634 
10635         // Is the caller requesting to dump a particular piece of data?
10636         if (opti < args.length) {
10637             String cmd = args[opti];
10638             opti++;
10639             // Is this a package name?
10640             if ("android".equals(cmd) || cmd.contains(".")) {
10641                 packageName = cmd;
10642                 // When dumping a single package, we always dump all of its
10643                 // filter information since the amount of data will be reasonable.
10644                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
10645             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
10646                 dumpState.setDump(DumpState.DUMP_LIBS);
10647             } else if ("f".equals(cmd) || "features".equals(cmd)) {
10648                 dumpState.setDump(DumpState.DUMP_FEATURES);
10649             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
10650                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
10651             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
10652                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
10653             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
10654                 dumpState.setDump(DumpState.DUMP_PREFERRED);
10655             } else if ("preferred-xml".equals(cmd)) {
10656                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
10657                 if (opti < args.length && "--full".equals(args[opti])) {
10658                     fullPreferred = true;
10659                     opti++;
10660                 }
10661             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
10662                 dumpState.setDump(DumpState.DUMP_PACKAGES);
10663             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
10664                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
10665             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
10666                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
10667             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
10668                 dumpState.setDump(DumpState.DUMP_MESSAGES);
10669             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
10670                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
10671             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
10672                 dumpState.setDump(DumpState.DUMP_KEYSETS);
10673             }
10674         }
10675 
10676         if (checkin) {
10677             pw.println("vers,1");
10678         }
10679 
10680         // reader
10681         synchronized (mPackages) {
10682             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
10683                 if (!checkin) {
10684                     if (dumpState.onTitlePrinted())
10685                         pw.println();
10686                     pw.println("Verifiers:");
10687                     pw.print("  Required: ");
10688                     pw.print(mRequiredVerifierPackage);
10689                     pw.print(" (uid=");
10690                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
10691                     pw.println(")");
10692                 } else if (mRequiredVerifierPackage != null) {
10693                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
10694                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
10695                 }
10696             }
10697 
10698             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
10699                 boolean printedHeader = false;
10700                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
10701                 while (it.hasNext()) {
10702                     String name = it.next();
10703                     SharedLibraryEntry ent = mSharedLibraries.get(name);
10704                     if (!checkin) {
10705                         if (!printedHeader) {
10706                             if (dumpState.onTitlePrinted())
10707                                 pw.println();
10708                             pw.println("Libraries:");
10709                             printedHeader = true;
10710                         }
10711                         pw.print("  ");
10712                     } else {
10713                         pw.print("lib,");
10714                     }
10715                     pw.print(name);
10716                     if (!checkin) {
10717                         pw.print(" -> ");
10718                     }
10719                     if (ent.path != null) {
10720                         if (!checkin) {
10721                             pw.print("(jar) ");
10722                             pw.print(ent.path);
10723                         } else {
10724                             pw.print(",jar,");
10725                             pw.print(ent.path);
10726                         }
10727                     } else {
10728                         if (!checkin) {
10729                             pw.print("(apk) ");
10730                             pw.print(ent.apk);
10731                         } else {
10732                             pw.print(",apk,");
10733                             pw.print(ent.apk);
10734                         }
10735                     }
10736                     pw.println();
10737                 }
10738             }
10739 
10740             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
10741                 if (dumpState.onTitlePrinted())
10742                     pw.println();
10743                 if (!checkin) {
10744                     pw.println("Features:");
10745                 }
10746                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
10747                 while (it.hasNext()) {
10748                     String name = it.next();
10749                     if (!checkin) {
10750                         pw.print("  ");
10751                     } else {
10752                         pw.print("feat,");
10753                     }
10754                     pw.println(name);
10755                 }
10756             }
10757 
10758             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
10759                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
10760                         : "Activity Resolver Table:", "  ", packageName,
10761                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10762                     dumpState.setTitlePrinted(true);
10763                 }
10764                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
10765                         : "Receiver Resolver Table:", "  ", packageName,
10766                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10767                     dumpState.setTitlePrinted(true);
10768                 }
10769                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
10770                         : "Service Resolver Table:", "  ", packageName,
10771                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10772                     dumpState.setTitlePrinted(true);
10773                 }
10774                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
10775                         : "Provider Resolver Table:", "  ", packageName,
10776                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10777                     dumpState.setTitlePrinted(true);
10778                 }
10779             }
10780 
10781             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
10782                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
10783                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
10784                     int user = mSettings.mPreferredActivities.keyAt(i);
10785                     if (pir.dump(pw,
10786                             dumpState.getTitlePrinted()
10787                                 ? "\nPreferred Activities User " + user + ":"
10788                                 : "Preferred Activities User " + user + ":", "  ",
10789                             packageName, true)) {
10790                         dumpState.setTitlePrinted(true);
10791                     }
10792                 }
10793             }
10794 
10795             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
10796                 pw.flush();
10797                 FileOutputStream fout = new FileOutputStream(fd);
10798                 BufferedOutputStream str = new BufferedOutputStream(fout);
10799                 XmlSerializer serializer = new FastXmlSerializer();
10800                 try {
10801                     serializer.setOutput(str, "utf-8");
10802                     serializer.startDocument(null, true);
10803                     serializer.setFeature(
10804                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
10805                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
10806                     serializer.endDocument();
10807                     serializer.flush();
10808                 } catch (IllegalArgumentException e) {
10809                     pw.println("Failed writing: " + e);
10810                 } catch (IllegalStateException e) {
10811                     pw.println("Failed writing: " + e);
10812                 } catch (IOException e) {
10813                     pw.println("Failed writing: " + e);
10814                 }
10815             }
10816 
10817             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
10818                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
10819             }
10820 
10821             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
10822                 boolean printedSomething = false;
10823                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
10824                     if (packageName != null && !packageName.equals(p.info.packageName)) {
10825                         continue;
10826                     }
10827                     if (!printedSomething) {
10828                         if (dumpState.onTitlePrinted())
10829                             pw.println();
10830                         pw.println("Registered ContentProviders:");
10831                         printedSomething = true;
10832                     }
10833                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
10834                     pw.print("    "); pw.println(p.toString());
10835                 }
10836                 printedSomething = false;
10837                 for (Map.Entry<String, PackageParser.Provider> entry :
10838                         mProvidersByAuthority.entrySet()) {
10839                     PackageParser.Provider p = entry.getValue();
10840                     if (packageName != null && !packageName.equals(p.info.packageName)) {
10841                         continue;
10842                     }
10843                     if (!printedSomething) {
10844                         if (dumpState.onTitlePrinted())
10845                             pw.println();
10846                         pw.println("ContentProvider Authorities:");
10847                         printedSomething = true;
10848                     }
10849                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
10850                     pw.print("    "); pw.println(p.toString());
10851                     if (p.info != null && p.info.applicationInfo != null) {
10852                         final String appInfo = p.info.applicationInfo.toString();
10853                         pw.print("      applicationInfo="); pw.println(appInfo);
10854                     }
10855                 }
10856             }
10857 
10858             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
10859                 mSettings.mKeySetManager.dump(pw, packageName, dumpState);
10860             }
10861 
10862             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
10863                 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
10864             }
10865 
10866             if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
10867                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
10868             }
10869 
10870             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
10871                 if (dumpState.onTitlePrinted())
10872                     pw.println();
10873                 mSettings.dumpReadMessagesLPr(pw, dumpState);
10874 
10875                 pw.println();
10876                 pw.println("Package warning messages:");
10877                 final File fname = getSettingsProblemFile();
10878                 FileInputStream in = null;
10879                 try {
10880                     in = new FileInputStream(fname);
10881                     final int avail = in.available();
10882                     final byte[] data = new byte[avail];
10883                     in.read(data);
10884                     pw.print(new String(data));
10885                 } catch (FileNotFoundException e) {
10886                 } catch (IOException e) {
10887                 } finally {
10888                     if (in != null) {
10889                         try {
10890                             in.close();
10891                         } catch (IOException e) {
10892                         }
10893                     }
10894                 }
10895             }
10896         }
10897     }
10898 
10899     // ------- apps on sdcard specific code -------
10900     static final boolean DEBUG_SD_INSTALL = false;
10901 
10902     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
10903 
10904     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
10905 
10906     private boolean mMediaMounted = false;
10907 
getEncryptKey()10908     private String getEncryptKey() {
10909         try {
10910             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
10911                     SD_ENCRYPTION_KEYSTORE_NAME);
10912             if (sdEncKey == null) {
10913                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
10914                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
10915                 if (sdEncKey == null) {
10916                     Slog.e(TAG, "Failed to create encryption keys");
10917                     return null;
10918                 }
10919             }
10920             return sdEncKey;
10921         } catch (NoSuchAlgorithmException nsae) {
10922             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
10923             return null;
10924         } catch (IOException ioe) {
10925             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
10926             return null;
10927         }
10928 
10929     }
10930 
getTempContainerId()10931     /* package */static String getTempContainerId() {
10932         int tmpIdx = 1;
10933         String list[] = PackageHelper.getSecureContainerList();
10934         if (list != null) {
10935             for (final String name : list) {
10936                 // Ignore null and non-temporary container entries
10937                 if (name == null || !name.startsWith(mTempContainerPrefix)) {
10938                     continue;
10939                 }
10940 
10941                 String subStr = name.substring(mTempContainerPrefix.length());
10942                 try {
10943                     int cid = Integer.parseInt(subStr);
10944                     if (cid >= tmpIdx) {
10945                         tmpIdx = cid + 1;
10946                     }
10947                 } catch (NumberFormatException e) {
10948                 }
10949             }
10950         }
10951         return mTempContainerPrefix + tmpIdx;
10952     }
10953 
10954     /*
10955      * Update media status on PackageManager.
10956      */
updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)10957     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
10958         int callingUid = Binder.getCallingUid();
10959         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10960             throw new SecurityException("Media status can only be updated by the system");
10961         }
10962         // reader; this apparently protects mMediaMounted, but should probably
10963         // be a different lock in that case.
10964         synchronized (mPackages) {
10965             Log.i(TAG, "Updating external media status from "
10966                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
10967                     + (mediaStatus ? "mounted" : "unmounted"));
10968             if (DEBUG_SD_INSTALL)
10969                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
10970                         + ", mMediaMounted=" + mMediaMounted);
10971             if (mediaStatus == mMediaMounted) {
10972                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
10973                         : 0, -1);
10974                 mHandler.sendMessage(msg);
10975                 return;
10976             }
10977             mMediaMounted = mediaStatus;
10978         }
10979         // Queue up an async operation since the package installation may take a
10980         // little while.
10981         mHandler.post(new Runnable() {
10982             public void run() {
10983                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
10984             }
10985         });
10986     }
10987 
10988     /**
10989      * Called by MountService when the initial ASECs to scan are available.
10990      * Should block until all the ASEC containers are finished being scanned.
10991      */
scanAvailableAsecs()10992     public void scanAvailableAsecs() {
10993         updateExternalMediaStatusInner(true, false, false);
10994     }
10995 
10996     /*
10997      * Collect information of applications on external media, map them against
10998      * existing containers and update information based on current mount status.
10999      * Please note that we always have to report status if reportStatus has been
11000      * set to true especially when unloading packages.
11001      */
updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)11002     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
11003             boolean externalStorage) {
11004         // Collection of uids
11005         int uidArr[] = null;
11006         // Collection of stale containers
11007         HashSet<String> removeCids = new HashSet<String>();
11008         // Collection of packages on external media with valid containers.
11009         HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>();
11010         // Get list of secure containers.
11011         final String list[] = PackageHelper.getSecureContainerList();
11012         if (list == null || list.length == 0) {
11013             Log.i(TAG, "No secure containers on sdcard");
11014         } else {
11015             // Process list of secure containers and categorize them
11016             // as active or stale based on their package internal state.
11017             int uidList[] = new int[list.length];
11018             int num = 0;
11019             // reader
11020             synchronized (mPackages) {
11021                 for (String cid : list) {
11022                     if (DEBUG_SD_INSTALL)
11023                         Log.i(TAG, "Processing container " + cid);
11024                     String pkgName = getAsecPackageName(cid);
11025                     if (pkgName == null) {
11026                         if (DEBUG_SD_INSTALL)
11027                             Log.i(TAG, "Container : " + cid + " stale");
11028                         removeCids.add(cid);
11029                         continue;
11030                     }
11031                     if (DEBUG_SD_INSTALL)
11032                         Log.i(TAG, "Looking for pkg : " + pkgName);
11033 
11034                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
11035                     if (ps == null) {
11036                         Log.i(TAG, "Deleting container with no matching settings " + cid);
11037                         removeCids.add(cid);
11038                         continue;
11039                     }
11040 
11041                     /*
11042                      * Skip packages that are not external if we're unmounting
11043                      * external storage.
11044                      */
11045                     if (externalStorage && !isMounted && !isExternal(ps)) {
11046                         continue;
11047                     }
11048 
11049                     final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
11050                     // The package status is changed only if the code path
11051                     // matches between settings and the container id.
11052                     if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
11053                         if (DEBUG_SD_INSTALL) {
11054                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
11055                                     + " at code path: " + ps.codePathString);
11056                         }
11057 
11058                         // We do have a valid package installed on sdcard
11059                         processCids.put(args, ps.codePathString);
11060                         final int uid = ps.appId;
11061                         if (uid != -1) {
11062                             uidList[num++] = uid;
11063                         }
11064                     } else {
11065                         Log.i(TAG, "Deleting stale container for " + cid);
11066                         removeCids.add(cid);
11067                     }
11068                 }
11069             }
11070 
11071             if (num > 0) {
11072                 // Sort uid list
11073                 Arrays.sort(uidList, 0, num);
11074                 // Throw away duplicates
11075                 uidArr = new int[num];
11076                 uidArr[0] = uidList[0];
11077                 int di = 0;
11078                 for (int i = 1; i < num; i++) {
11079                     if (uidList[i - 1] != uidList[i]) {
11080                         uidArr[di++] = uidList[i];
11081                     }
11082                 }
11083             }
11084         }
11085         // Process packages with valid entries.
11086         if (isMounted) {
11087             if (DEBUG_SD_INSTALL)
11088                 Log.i(TAG, "Loading packages");
11089             loadMediaPackages(processCids, uidArr, removeCids);
11090             startCleaningPackages();
11091         } else {
11092             if (DEBUG_SD_INSTALL)
11093                 Log.i(TAG, "Unloading packages");
11094             unloadMediaPackages(processCids, uidArr, reportStatus);
11095         }
11096     }
11097 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)11098    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
11099            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
11100         int size = pkgList.size();
11101         if (size > 0) {
11102             // Send broadcasts here
11103             Bundle extras = new Bundle();
11104             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
11105                     .toArray(new String[size]));
11106             if (uidArr != null) {
11107                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
11108             }
11109             if (replacing) {
11110                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
11111             }
11112             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
11113                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
11114             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
11115         }
11116     }
11117 
11118    /*
11119      * Look at potentially valid container ids from processCids If package
11120      * information doesn't match the one on record or package scanning fails,
11121      * the cid is added to list of removeCids. We currently don't delete stale
11122      * containers.
11123      */
loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], HashSet<String> removeCids)11124    private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
11125             HashSet<String> removeCids) {
11126         ArrayList<String> pkgList = new ArrayList<String>();
11127         Set<AsecInstallArgs> keys = processCids.keySet();
11128         boolean doGc = false;
11129         for (AsecInstallArgs args : keys) {
11130             String codePath = processCids.get(args);
11131             if (DEBUG_SD_INSTALL)
11132                 Log.i(TAG, "Loading container : " + args.cid);
11133             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11134             try {
11135                 // Make sure there are no container errors first.
11136                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
11137                     Slog.e(TAG, "Failed to mount cid : " + args.cid
11138                             + " when installing from sdcard");
11139                     continue;
11140                 }
11141                 // Check code path here.
11142                 if (codePath == null || !codePath.equals(args.getCodePath())) {
11143                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
11144                             + " does not match one in settings " + codePath);
11145                     continue;
11146                 }
11147                 // Parse package
11148                 int parseFlags = mDefParseFlags;
11149                 if (args.isExternal()) {
11150                     parseFlags |= PackageParser.PARSE_ON_SDCARD;
11151                 }
11152                 if (args.isFwdLocked()) {
11153                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
11154                 }
11155 
11156                 doGc = true;
11157                 synchronized (mInstallLock) {
11158                     final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
11159                             0, 0, null);
11160                     // Scan the package
11161                     if (pkg != null) {
11162                         /*
11163                          * TODO why is the lock being held? doPostInstall is
11164                          * called in other places without the lock. This needs
11165                          * to be straightened out.
11166                          */
11167                         // writer
11168                         synchronized (mPackages) {
11169                             retCode = PackageManager.INSTALL_SUCCEEDED;
11170                             pkgList.add(pkg.packageName);
11171                             // Post process args
11172                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
11173                                     pkg.applicationInfo.uid);
11174                         }
11175                     } else {
11176                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
11177                     }
11178                 }
11179 
11180             } finally {
11181                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
11182                     // Don't destroy container here. Wait till gc clears things
11183                     // up.
11184                     removeCids.add(args.cid);
11185                 }
11186             }
11187         }
11188         // writer
11189         synchronized (mPackages) {
11190             // If the platform SDK has changed since the last time we booted,
11191             // we need to re-grant app permission to catch any new ones that
11192             // appear. This is really a hack, and means that apps can in some
11193             // cases get permissions that the user didn't initially explicitly
11194             // allow... it would be nice to have some better way to handle
11195             // this situation.
11196             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
11197             if (regrantPermissions)
11198                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
11199                         + mSdkVersion + "; regranting permissions for external storage");
11200             mSettings.mExternalSdkPlatform = mSdkVersion;
11201 
11202             // Make sure group IDs have been assigned, and any permission
11203             // changes in other apps are accounted for
11204             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
11205                     | (regrantPermissions
11206                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
11207                             : 0));
11208             // can downgrade to reader
11209             // Persist settings
11210             mSettings.writeLPr();
11211         }
11212         // Send a broadcast to let everyone know we are done processing
11213         if (pkgList.size() > 0) {
11214             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
11215         }
11216         // Force gc to avoid any stale parser references that we might have.
11217         if (doGc) {
11218             Runtime.getRuntime().gc();
11219         }
11220         // List stale containers and destroy stale temporary containers.
11221         if (removeCids != null) {
11222             for (String cid : removeCids) {
11223                 if (cid.startsWith(mTempContainerPrefix)) {
11224                     Log.i(TAG, "Destroying stale temporary container " + cid);
11225                     PackageHelper.destroySdDir(cid);
11226                 } else {
11227                     Log.w(TAG, "Container " + cid + " is stale");
11228                }
11229            }
11230         }
11231     }
11232 
11233    /*
11234      * Utility method to unload a list of specified containers
11235      */
unloadAllContainers(Set<AsecInstallArgs> cidArgs)11236     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
11237         // Just unmount all valid containers.
11238         for (AsecInstallArgs arg : cidArgs) {
11239             synchronized (mInstallLock) {
11240                 arg.doPostDeleteLI(false);
11241            }
11242        }
11243    }
11244 
11245     /*
11246      * Unload packages mounted on external media. This involves deleting package
11247      * data from internal structures, sending broadcasts about diabled packages,
11248      * gc'ing to free up references, unmounting all secure containers
11249      * corresponding to packages on external media, and posting a
11250      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
11251      * that we always have to post this message if status has been requested no
11252      * matter what.
11253      */
unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)11254     private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
11255             final boolean reportStatus) {
11256         if (DEBUG_SD_INSTALL)
11257             Log.i(TAG, "unloading media packages");
11258         ArrayList<String> pkgList = new ArrayList<String>();
11259         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
11260         final Set<AsecInstallArgs> keys = processCids.keySet();
11261         for (AsecInstallArgs args : keys) {
11262             String pkgName = args.getPackageName();
11263             if (DEBUG_SD_INSTALL)
11264                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
11265             // Delete package internally
11266             PackageRemovedInfo outInfo = new PackageRemovedInfo();
11267             synchronized (mInstallLock) {
11268                 boolean res = deletePackageLI(pkgName, null, false, null, null,
11269                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
11270                 if (res) {
11271                     pkgList.add(pkgName);
11272                 } else {
11273                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
11274                     failedList.add(args);
11275                 }
11276             }
11277         }
11278 
11279         // reader
11280         synchronized (mPackages) {
11281             // We didn't update the settings after removing each package;
11282             // write them now for all packages.
11283             mSettings.writeLPr();
11284         }
11285 
11286         // We have to absolutely send UPDATED_MEDIA_STATUS only
11287         // after confirming that all the receivers processed the ordered
11288         // broadcast when packages get disabled, force a gc to clean things up.
11289         // and unload all the containers.
11290         if (pkgList.size() > 0) {
11291             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
11292                     new IIntentReceiver.Stub() {
11293                 public void performReceive(Intent intent, int resultCode, String data,
11294                         Bundle extras, boolean ordered, boolean sticky,
11295                         int sendingUser) throws RemoteException {
11296                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
11297                             reportStatus ? 1 : 0, 1, keys);
11298                     mHandler.sendMessage(msg);
11299                 }
11300             });
11301         } else {
11302             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
11303                     keys);
11304             mHandler.sendMessage(msg);
11305         }
11306     }
11307 
11308     /** Binder call */
11309     @Override
movePackage(final String packageName, final IPackageMoveObserver observer, final int flags)11310     public void movePackage(final String packageName, final IPackageMoveObserver observer,
11311             final int flags) {
11312         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
11313         UserHandle user = new UserHandle(UserHandle.getCallingUserId());
11314         int returnCode = PackageManager.MOVE_SUCCEEDED;
11315         int currFlags = 0;
11316         int newFlags = 0;
11317         // reader
11318         synchronized (mPackages) {
11319             PackageParser.Package pkg = mPackages.get(packageName);
11320             if (pkg == null) {
11321                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
11322             } else {
11323                 // Disable moving fwd locked apps and system packages
11324                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
11325                     Slog.w(TAG, "Cannot move system application");
11326                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
11327                 } else if (pkg.mOperationPending) {
11328                     Slog.w(TAG, "Attempt to move package which has pending operations");
11329                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
11330                 } else {
11331                     // Find install location first
11332                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
11333                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
11334                         Slog.w(TAG, "Ambigous flags specified for move location.");
11335                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
11336                     } else {
11337                         newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL
11338                                 : PackageManager.INSTALL_INTERNAL;
11339                         currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
11340                                 : PackageManager.INSTALL_INTERNAL;
11341 
11342                         if (newFlags == currFlags) {
11343                             Slog.w(TAG, "No move required. Trying to move to same location");
11344                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
11345                         } else {
11346                             if (isForwardLocked(pkg)) {
11347                                 currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
11348                                 newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
11349                             }
11350                         }
11351                     }
11352                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
11353                         pkg.mOperationPending = true;
11354                     }
11355                 }
11356             }
11357 
11358             /*
11359              * TODO this next block probably shouldn't be inside the lock. We
11360              * can't guarantee these won't change after this is fired off
11361              * anyway.
11362              */
11363             if (returnCode != PackageManager.MOVE_SUCCEEDED) {
11364                 processPendingMove(new MoveParams(null, observer, 0, packageName,
11365                         null, -1, user),
11366                         returnCode);
11367             } else {
11368                 Message msg = mHandler.obtainMessage(INIT_COPY);
11369                 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
11370                         pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
11371                 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
11372                         pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user);
11373                 msg.obj = mp;
11374                 mHandler.sendMessage(msg);
11375             }
11376         }
11377     }
11378 
processPendingMove(final MoveParams mp, final int currentStatus)11379     private void processPendingMove(final MoveParams mp, final int currentStatus) {
11380         // Queue up an async operation since the package deletion may take a
11381         // little while.
11382         mHandler.post(new Runnable() {
11383             public void run() {
11384                 // TODO fix this; this does nothing.
11385                 mHandler.removeCallbacks(this);
11386                 int returnCode = currentStatus;
11387                 if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
11388                     int uidArr[] = null;
11389                     ArrayList<String> pkgList = null;
11390                     synchronized (mPackages) {
11391                         PackageParser.Package pkg = mPackages.get(mp.packageName);
11392                         if (pkg == null) {
11393                             Slog.w(TAG, " Package " + mp.packageName
11394                                     + " doesn't exist. Aborting move");
11395                             returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
11396                         } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
11397                             Slog.w(TAG, "Package " + mp.packageName + " code path changed from "
11398                                     + mp.srcArgs.getCodePath() + " to "
11399                                     + pkg.applicationInfo.sourceDir
11400                                     + " Aborting move and returning error");
11401                             returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
11402                         } else {
11403                             uidArr = new int[] {
11404                                 pkg.applicationInfo.uid
11405                             };
11406                             pkgList = new ArrayList<String>();
11407                             pkgList.add(mp.packageName);
11408                         }
11409                     }
11410                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
11411                         // Send resources unavailable broadcast
11412                         sendResourcesChangedBroadcast(false, true, pkgList, uidArr, null);
11413                         // Update package code and resource paths
11414                         synchronized (mInstallLock) {
11415                             synchronized (mPackages) {
11416                                 PackageParser.Package pkg = mPackages.get(mp.packageName);
11417                                 // Recheck for package again.
11418                                 if (pkg == null) {
11419                                     Slog.w(TAG, " Package " + mp.packageName
11420                                             + " doesn't exist. Aborting move");
11421                                     returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
11422                                 } else if (!mp.srcArgs.getCodePath().equals(
11423                                         pkg.applicationInfo.sourceDir)) {
11424                                     Slog.w(TAG, "Package " + mp.packageName
11425                                             + " code path changed from " + mp.srcArgs.getCodePath()
11426                                             + " to " + pkg.applicationInfo.sourceDir
11427                                             + " Aborting move and returning error");
11428                                     returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
11429                                 } else {
11430                                     final String oldCodePath = pkg.mPath;
11431                                     final String newCodePath = mp.targetArgs.getCodePath();
11432                                     final String newResPath = mp.targetArgs.getResourcePath();
11433                                     final String newNativePath = mp.targetArgs
11434                                             .getNativeLibraryPath();
11435 
11436                                     final File newNativeDir = new File(newNativePath);
11437 
11438                                     if (!isForwardLocked(pkg) && !isExternal(pkg)) {
11439                                         NativeLibraryHelper.copyNativeBinariesIfNeededLI(
11440                                                 new File(newCodePath), newNativeDir);
11441                                     }
11442                                     final int[] users = sUserManager.getUserIds();
11443                                     for (int user : users) {
11444                                         if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
11445                                                 newNativePath, user) < 0) {
11446                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
11447                                         }
11448                                     }
11449 
11450                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
11451                                         pkg.mPath = newCodePath;
11452                                         // Move dex files around
11453                                         if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) {
11454                                             // Moving of dex files failed. Set
11455                                             // error code and abort move.
11456                                             pkg.mPath = pkg.mScanPath;
11457                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
11458                                         }
11459                                     }
11460 
11461                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
11462                                         pkg.mScanPath = newCodePath;
11463                                         pkg.applicationInfo.sourceDir = newCodePath;
11464                                         pkg.applicationInfo.publicSourceDir = newResPath;
11465                                         pkg.applicationInfo.nativeLibraryDir = newNativePath;
11466                                         PackageSetting ps = (PackageSetting) pkg.mExtras;
11467                                         ps.codePath = new File(pkg.applicationInfo.sourceDir);
11468                                         ps.codePathString = ps.codePath.getPath();
11469                                         ps.resourcePath = new File(
11470                                                 pkg.applicationInfo.publicSourceDir);
11471                                         ps.resourcePathString = ps.resourcePath.getPath();
11472                                         ps.nativeLibraryPathString = newNativePath;
11473                                         // Set the application info flag
11474                                         // correctly.
11475                                         if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
11476                                             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
11477                                         } else {
11478                                             pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
11479                                         }
11480                                         ps.setFlags(pkg.applicationInfo.flags);
11481                                         mAppDirs.remove(oldCodePath);
11482                                         mAppDirs.put(newCodePath, pkg);
11483                                         // Persist settings
11484                                         mSettings.writeLPr();
11485                                     }
11486                                 }
11487                             }
11488                         }
11489                         // Send resources available broadcast
11490                         sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
11491                     }
11492                 }
11493                 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
11494                     // Clean up failed installation
11495                     if (mp.targetArgs != null) {
11496                         mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
11497                                 -1);
11498                     }
11499                 } else {
11500                     // Force a gc to clear things up.
11501                     Runtime.getRuntime().gc();
11502                     // Delete older code
11503                     synchronized (mInstallLock) {
11504                         mp.srcArgs.doPostDeleteLI(true);
11505                     }
11506                 }
11507 
11508                 // Allow more operations on this file if we didn't fail because
11509                 // an operation was already pending for this package.
11510                 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
11511                     synchronized (mPackages) {
11512                         PackageParser.Package pkg = mPackages.get(mp.packageName);
11513                         if (pkg != null) {
11514                             pkg.mOperationPending = false;
11515                        }
11516                    }
11517                 }
11518 
11519                 IPackageMoveObserver observer = mp.observer;
11520                 if (observer != null) {
11521                     try {
11522                         observer.packageMoved(mp.packageName, returnCode);
11523                     } catch (RemoteException e) {
11524                         Log.i(TAG, "Observer no longer exists.");
11525                     }
11526                 }
11527             }
11528         });
11529     }
11530 
setInstallLocation(int loc)11531     public boolean setInstallLocation(int loc) {
11532         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
11533                 null);
11534         if (getInstallLocation() == loc) {
11535             return true;
11536         }
11537         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
11538                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
11539             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
11540                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
11541             return true;
11542         }
11543         return false;
11544    }
11545 
getInstallLocation()11546     public int getInstallLocation() {
11547         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11548                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
11549                 PackageHelper.APP_INSTALL_AUTO);
11550     }
11551 
11552     /** Called by UserManagerService */
cleanUpUserLILPw(int userHandle)11553     void cleanUpUserLILPw(int userHandle) {
11554         mDirtyUsers.remove(userHandle);
11555         mSettings.removeUserLPr(userHandle);
11556         mPendingBroadcasts.remove(userHandle);
11557         if (mInstaller != null) {
11558             // Technically, we shouldn't be doing this with the package lock
11559             // held.  However, this is very rare, and there is already so much
11560             // other disk I/O going on, that we'll let it slide for now.
11561             mInstaller.removeUserDataDirs(userHandle);
11562         }
11563     }
11564 
11565     /** Called by UserManagerService */
createNewUserLILPw(int userHandle, File path)11566     void createNewUserLILPw(int userHandle, File path) {
11567         if (mInstaller != null) {
11568             mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
11569         }
11570     }
11571 
11572     @Override
getVerifierDeviceIdentity()11573     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
11574         mContext.enforceCallingOrSelfPermission(
11575                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11576                 "Only package verification agents can read the verifier device identity");
11577 
11578         synchronized (mPackages) {
11579             return mSettings.getVerifierDeviceIdentityLPw();
11580         }
11581     }
11582 
11583     @Override
setPermissionEnforced(String permission, boolean enforced)11584     public void setPermissionEnforced(String permission, boolean enforced) {
11585         mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
11586         if (READ_EXTERNAL_STORAGE.equals(permission)) {
11587             synchronized (mPackages) {
11588                 if (mSettings.mReadExternalStorageEnforced == null
11589                         || mSettings.mReadExternalStorageEnforced != enforced) {
11590                     mSettings.mReadExternalStorageEnforced = enforced;
11591                     mSettings.writeLPr();
11592                 }
11593             }
11594             // kill any non-foreground processes so we restart them and
11595             // grant/revoke the GID.
11596             final IActivityManager am = ActivityManagerNative.getDefault();
11597             if (am != null) {
11598                 final long token = Binder.clearCallingIdentity();
11599                 try {
11600                     am.killProcessesBelowForeground("setPermissionEnforcement");
11601                 } catch (RemoteException e) {
11602                 } finally {
11603                     Binder.restoreCallingIdentity(token);
11604                 }
11605             }
11606         } else {
11607             throw new IllegalArgumentException("No selective enforcement for " + permission);
11608         }
11609     }
11610 
11611     @Override
11612     @Deprecated
isPermissionEnforced(String permission)11613     public boolean isPermissionEnforced(String permission) {
11614         return true;
11615     }
11616 
isStorageLow()11617     public boolean isStorageLow() {
11618         final long token = Binder.clearCallingIdentity();
11619         try {
11620             final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
11621                     .getService(DeviceStorageMonitorService.SERVICE);
11622             return dsm.isMemoryLow();
11623         } finally {
11624             Binder.restoreCallingIdentity(token);
11625         }
11626     }
11627 }
11628