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