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