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 android.content.pm.PackageManager.INSTALL_EXTERNAL;
27 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
28 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
29 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
30 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
31 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
32 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
33 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
34 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
35 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
36 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
37 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
38 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
39 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
45 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
46 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
47 import static android.content.pm.PackageParser.isApkFile;
48 import static android.os.Process.PACKAGE_INFO_GID;
49 import static android.os.Process.SYSTEM_UID;
50 import static android.system.OsConstants.O_CREAT;
51 import static android.system.OsConstants.O_RDWR;
52 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
53 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
54 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
55 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
56 import static com.android.internal.util.ArrayUtils.appendInt;
57 import static com.android.internal.util.ArrayUtils.removeInt;
58 
59 import android.util.ArrayMap;
60 
61 import com.android.internal.R;
62 import com.android.internal.app.IMediaContainerService;
63 import com.android.internal.app.ResolverActivity;
64 import com.android.internal.content.NativeLibraryHelper;
65 import com.android.internal.content.PackageHelper;
66 import com.android.internal.os.IParcelFileDescriptorFactory;
67 import com.android.internal.util.ArrayUtils;
68 import com.android.internal.util.FastPrintWriter;
69 import com.android.internal.util.FastXmlSerializer;
70 import com.android.internal.util.IndentingPrintWriter;
71 import com.android.server.EventLogTags;
72 import com.android.server.IntentResolver;
73 import com.android.server.LocalServices;
74 import com.android.server.ServiceThread;
75 import com.android.server.SystemConfig;
76 import com.android.server.Watchdog;
77 import com.android.server.pm.Settings.DatabaseVersion;
78 import com.android.server.storage.DeviceStorageMonitorInternal;
79 
80 import org.xmlpull.v1.XmlSerializer;
81 
82 import android.app.ActivityManager;
83 import android.app.ActivityManagerNative;
84 import android.app.AppGlobals;
85 import android.app.IActivityManager;
86 import android.app.admin.IDevicePolicyManager;
87 import android.app.backup.IBackupManager;
88 import android.app.usage.UsageStats;
89 import android.app.usage.UsageStatsManager;
90 import android.content.BroadcastReceiver;
91 import android.content.ComponentName;
92 import android.content.Context;
93 import android.content.IIntentReceiver;
94 import android.content.Intent;
95 import android.content.IntentFilter;
96 import android.content.IntentSender;
97 import android.content.IntentSender.SendIntentException;
98 import android.content.ServiceConnection;
99 import android.content.pm.ActivityInfo;
100 import android.content.pm.ApplicationInfo;
101 import android.content.pm.FeatureInfo;
102 import android.content.pm.IPackageDataObserver;
103 import android.content.pm.IPackageDeleteObserver;
104 import android.content.pm.IPackageDeleteObserver2;
105 import android.content.pm.IPackageInstallObserver2;
106 import android.content.pm.IPackageInstaller;
107 import android.content.pm.IPackageManager;
108 import android.content.pm.IPackageMoveObserver;
109 import android.content.pm.IPackageStatsObserver;
110 import android.content.pm.InstrumentationInfo;
111 import android.content.pm.KeySet;
112 import android.content.pm.ManifestDigest;
113 import android.content.pm.PackageCleanItem;
114 import android.content.pm.PackageInfo;
115 import android.content.pm.PackageInfoLite;
116 import android.content.pm.PackageInstaller;
117 import android.content.pm.PackageManager;
118 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
119 import android.content.pm.PackageParser.ActivityIntentInfo;
120 import android.content.pm.PackageParser.PackageLite;
121 import android.content.pm.PackageParser.PackageParserException;
122 import android.content.pm.PackageParser;
123 import android.content.pm.PackageStats;
124 import android.content.pm.PackageUserState;
125 import android.content.pm.ParceledListSlice;
126 import android.content.pm.PermissionGroupInfo;
127 import android.content.pm.PermissionInfo;
128 import android.content.pm.ProviderInfo;
129 import android.content.pm.ResolveInfo;
130 import android.content.pm.ServiceInfo;
131 import android.content.pm.Signature;
132 import android.content.pm.UserInfo;
133 import android.content.pm.VerificationParams;
134 import android.content.pm.VerifierDeviceIdentity;
135 import android.content.pm.VerifierInfo;
136 import android.content.res.Resources;
137 import android.hardware.display.DisplayManager;
138 import android.net.Uri;
139 import android.os.Binder;
140 import android.os.Build;
141 import android.os.Bundle;
142 import android.os.Environment;
143 import android.os.Environment.UserEnvironment;
144 import android.os.storage.IMountService;
145 import android.os.storage.StorageManager;
146 import android.os.Debug;
147 import android.os.FileUtils;
148 import android.os.Handler;
149 import android.os.IBinder;
150 import android.os.Looper;
151 import android.os.Message;
152 import android.os.Parcel;
153 import android.os.ParcelFileDescriptor;
154 import android.os.Process;
155 import android.os.RemoteException;
156 import android.os.SELinux;
157 import android.os.ServiceManager;
158 import android.os.SystemClock;
159 import android.os.SystemProperties;
160 import android.os.UserHandle;
161 import android.os.UserManager;
162 import android.security.KeyStore;
163 import android.security.SystemKeyStore;
164 import android.system.ErrnoException;
165 import android.system.Os;
166 import android.system.StructStat;
167 import android.text.TextUtils;
168 import android.text.format.DateUtils;
169 import android.util.ArraySet;
170 import android.util.AtomicFile;
171 import android.util.DisplayMetrics;
172 import android.util.EventLog;
173 import android.util.ExceptionUtils;
174 import android.util.Log;
175 import android.util.LogPrinter;
176 import android.util.PrintStreamPrinter;
177 import android.util.Slog;
178 import android.util.SparseArray;
179 import android.util.SparseBooleanArray;
180 import android.view.Display;
181 
182 import java.io.BufferedInputStream;
183 import java.io.BufferedOutputStream;
184 import java.io.BufferedReader;
185 import java.io.File;
186 import java.io.FileDescriptor;
187 import java.io.FileInputStream;
188 import java.io.FileNotFoundException;
189 import java.io.FileOutputStream;
190 import java.io.FileReader;
191 import java.io.FilenameFilter;
192 import java.io.IOException;
193 import java.io.InputStream;
194 import java.io.PrintWriter;
195 import java.nio.charset.StandardCharsets;
196 import java.security.NoSuchAlgorithmException;
197 import java.security.PublicKey;
198 import java.security.cert.CertificateEncodingException;
199 import java.security.cert.CertificateException;
200 import java.text.SimpleDateFormat;
201 import java.util.ArrayList;
202 import java.util.Arrays;
203 import java.util.Collection;
204 import java.util.Collections;
205 import java.util.Comparator;
206 import java.util.Date;
207 import java.util.Iterator;
208 import java.util.List;
209 import java.util.Map;
210 import java.util.Objects;
211 import java.util.Set;
212 import java.util.concurrent.atomic.AtomicBoolean;
213 import java.util.concurrent.atomic.AtomicLong;
214 
215 import dalvik.system.DexFile;
216 import dalvik.system.StaleDexCacheError;
217 import dalvik.system.VMRuntime;
218 
219 import libcore.io.IoUtils;
220 import libcore.util.EmptyArray;
221 
222 /**
223  * Keep track of all those .apks everywhere.
224  *
225  * This is very central to the platform's security; please run the unit
226  * tests whenever making modifications here:
227  *
228 mmm frameworks/base/tests/AndroidTests
229 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
230 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
231  *
232  * {@hide}
233  */
234 public class PackageManagerService extends IPackageManager.Stub {
235     static final String TAG = "PackageManager";
236     static final boolean DEBUG_SETTINGS = false;
237     static final boolean DEBUG_PREFERRED = false;
238     static final boolean DEBUG_UPGRADE = false;
239     private static final boolean DEBUG_INSTALL = false;
240     private static final boolean DEBUG_REMOVE = false;
241     private static final boolean DEBUG_BROADCASTS = false;
242     private static final boolean DEBUG_SHOW_INFO = false;
243     private static final boolean DEBUG_PACKAGE_INFO = false;
244     private static final boolean DEBUG_INTENT_MATCHING = false;
245     private static final boolean DEBUG_PACKAGE_SCANNING = false;
246     private static final boolean DEBUG_VERIFY = false;
247     private static final boolean DEBUG_DEXOPT = false;
248     private static final boolean DEBUG_ABI_SELECTION = false;
249 
250     private static final int RADIO_UID = Process.PHONE_UID;
251     private static final int LOG_UID = Process.LOG_UID;
252     private static final int NFC_UID = Process.NFC_UID;
253     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
254     private static final int SHELL_UID = Process.SHELL_UID;
255 
256     // Cap the size of permission trees that 3rd party apps can define
257     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
258 
259     // Suffix used during package installation when copying/moving
260     // package apks to install directory.
261     private static final String INSTALL_PACKAGE_SUFFIX = "-";
262 
263     static final int SCAN_NO_DEX = 1<<1;
264     static final int SCAN_FORCE_DEX = 1<<2;
265     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
266     static final int SCAN_NEW_INSTALL = 1<<4;
267     static final int SCAN_NO_PATHS = 1<<5;
268     static final int SCAN_UPDATE_TIME = 1<<6;
269     static final int SCAN_DEFER_DEX = 1<<7;
270     static final int SCAN_BOOTING = 1<<8;
271     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
272     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
273     static final int SCAN_REPLACING = 1<<11;
274 
275     static final int REMOVE_CHATTY = 1<<16;
276 
277     /**
278      * Timeout (in milliseconds) after which the watchdog should declare that
279      * our handler thread is wedged.  The usual default for such things is one
280      * minute but we sometimes do very lengthy I/O operations on this thread,
281      * such as installing multi-gigabyte applications, so ours needs to be longer.
282      */
283     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
284 
285     /**
286      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
287      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
288      * settings entry if available, otherwise we use the hardcoded default.  If it's been
289      * more than this long since the last fstrim, we force one during the boot sequence.
290      *
291      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
292      * one gets run at the next available charging+idle time.  This final mandatory
293      * no-fstrim check kicks in only of the other scheduling criteria is never met.
294      */
295     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
296 
297     /**
298      * Whether verification is enabled by default.
299      */
300     private static final boolean DEFAULT_VERIFY_ENABLE = true;
301 
302     /**
303      * The default maximum time to wait for the verification agent to return in
304      * milliseconds.
305      */
306     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
307 
308     /**
309      * The default response for package verification timeout.
310      *
311      * This can be either PackageManager.VERIFICATION_ALLOW or
312      * PackageManager.VERIFICATION_REJECT.
313      */
314     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
315 
316     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
317 
318     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
319             DEFAULT_CONTAINER_PACKAGE,
320             "com.android.defcontainer.DefaultContainerService");
321 
322     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
323 
324     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
325 
326     private static String sPreferredInstructionSet;
327 
328     final ServiceThread mHandlerThread;
329 
330     private static final String IDMAP_PREFIX = "/data/resource-cache/";
331     private static final String IDMAP_SUFFIX = "@idmap";
332 
333     final PackageHandler mHandler;
334 
335     /**
336      * Messages for {@link #mHandler} that need to wait for system ready before
337      * being dispatched.
338      */
339     private ArrayList<Message> mPostSystemReadyMessages;
340 
341     final int mSdkVersion = Build.VERSION.SDK_INT;
342 
343     final Context mContext;
344     final boolean mFactoryTest;
345     final boolean mOnlyCore;
346     final boolean mLazyDexOpt;
347     final long mDexOptLRUThresholdInMills;
348     final DisplayMetrics mMetrics;
349     final int mDefParseFlags;
350     final String[] mSeparateProcesses;
351     final boolean mIsUpgrade;
352 
353     // This is where all application persistent data goes.
354     final File mAppDataDir;
355 
356     // This is where all application persistent data goes for secondary users.
357     final File mUserAppDataDir;
358 
359     /** The location for ASEC container files on internal storage. */
360     final String mAsecInternalPath;
361 
362     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
363     // LOCK HELD.  Can be called with mInstallLock held.
364     final Installer mInstaller;
365 
366     /** Directory where installed third-party apps stored */
367     final File mAppInstallDir;
368 
369     /**
370      * Directory to which applications installed internally have their
371      * 32 bit native libraries copied.
372      */
373     private File mAppLib32InstallDir;
374 
375     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
376     // apps.
377     final File mDrmAppPrivateInstallDir;
378 
379     // ----------------------------------------------------------------
380 
381     // Lock for state used when installing and doing other long running
382     // operations.  Methods that must be called with this lock held have
383     // the suffix "LI".
384     final Object mInstallLock = new Object();
385 
386     // ----------------------------------------------------------------
387 
388     // Keys are String (package name), values are Package.  This also serves
389     // as the lock for the global state.  Methods that must be called with
390     // this lock held have the prefix "LP".
391     final ArrayMap<String, PackageParser.Package> mPackages =
392             new ArrayMap<String, PackageParser.Package>();
393 
394     // Tracks available target package names -> overlay package paths.
395     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
396         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
397 
398     final Settings mSettings;
399     boolean mRestoredSettings;
400 
401     // System configuration read by SystemConfig.
402     final int[] mGlobalGids;
403     final SparseArray<ArraySet<String>> mSystemPermissions;
404     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
405 
406     // If mac_permissions.xml was found for seinfo labeling.
407     boolean mFoundPolicyFile;
408 
409     // If a recursive restorecon of /data/data/<pkg> is needed.
410     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
411 
412     public static final class SharedLibraryEntry {
413         public final String path;
414         public final String apk;
415 
SharedLibraryEntry(String _path, String _apk)416         SharedLibraryEntry(String _path, String _apk) {
417             path = _path;
418             apk = _apk;
419         }
420     }
421 
422     // Currently known shared libraries.
423     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
424             new ArrayMap<String, SharedLibraryEntry>();
425 
426     // All available activities, for your resolving pleasure.
427     final ActivityIntentResolver mActivities =
428             new ActivityIntentResolver();
429 
430     // All available receivers, for your resolving pleasure.
431     final ActivityIntentResolver mReceivers =
432             new ActivityIntentResolver();
433 
434     // All available services, for your resolving pleasure.
435     final ServiceIntentResolver mServices = new ServiceIntentResolver();
436 
437     // All available providers, for your resolving pleasure.
438     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
439 
440     // Mapping from provider base names (first directory in content URI codePath)
441     // to the provider information.
442     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
443             new ArrayMap<String, PackageParser.Provider>();
444 
445     // Mapping from instrumentation class names to info about them.
446     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
447             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
448 
449     // Mapping from permission names to info about them.
450     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
451             new ArrayMap<String, PackageParser.PermissionGroup>();
452 
453     // Packages whose data we have transfered into another package, thus
454     // should no longer exist.
455     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
456 
457     // Broadcast actions that are only available to the system.
458     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
459 
460     /** List of packages waiting for verification. */
461     final SparseArray<PackageVerificationState> mPendingVerification
462             = new SparseArray<PackageVerificationState>();
463 
464     /** Set of packages associated with each app op permission. */
465     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
466 
467     final PackageInstallerService mInstallerService;
468 
469     ArraySet<PackageParser.Package> mDeferredDexOpt = null;
470 
471     // Cache of users who need badging.
472     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
473 
474     /** Token for keys in mPendingVerification. */
475     private int mPendingVerificationToken = 0;
476 
477     volatile boolean mSystemReady;
478     volatile boolean mSafeMode;
479     volatile boolean mHasSystemUidErrors;
480 
481     ApplicationInfo mAndroidApplication;
482     final ActivityInfo mResolveActivity = new ActivityInfo();
483     final ResolveInfo mResolveInfo = new ResolveInfo();
484     ComponentName mResolveComponentName;
485     PackageParser.Package mPlatformPackage;
486     ComponentName mCustomResolverComponentName;
487 
488     boolean mResolverReplaced = false;
489 
490     // Set of pending broadcasts for aggregating enable/disable of components.
491     static class PendingPackageBroadcasts {
492         // for each user id, a map of <package name -> components within that package>
493         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
494 
PendingPackageBroadcasts()495         public PendingPackageBroadcasts() {
496             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
497         }
498 
get(int userId, String packageName)499         public ArrayList<String> get(int userId, String packageName) {
500             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
501             return packages.get(packageName);
502         }
503 
put(int userId, String packageName, ArrayList<String> components)504         public void put(int userId, String packageName, ArrayList<String> components) {
505             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
506             packages.put(packageName, components);
507         }
508 
remove(int userId, String packageName)509         public void remove(int userId, String packageName) {
510             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
511             if (packages != null) {
512                 packages.remove(packageName);
513             }
514         }
515 
remove(int userId)516         public void remove(int userId) {
517             mUidMap.remove(userId);
518         }
519 
userIdCount()520         public int userIdCount() {
521             return mUidMap.size();
522         }
523 
userIdAt(int n)524         public int userIdAt(int n) {
525             return mUidMap.keyAt(n);
526         }
527 
packagesForUserId(int userId)528         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
529             return mUidMap.get(userId);
530         }
531 
size()532         public int size() {
533             // total number of pending broadcast entries across all userIds
534             int num = 0;
535             for (int i = 0; i< mUidMap.size(); i++) {
536                 num += mUidMap.valueAt(i).size();
537             }
538             return num;
539         }
540 
clear()541         public void clear() {
542             mUidMap.clear();
543         }
544 
getOrAllocate(int userId)545         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
546             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
547             if (map == null) {
548                 map = new ArrayMap<String, ArrayList<String>>();
549                 mUidMap.put(userId, map);
550             }
551             return map;
552         }
553     }
554     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
555 
556     // Service Connection to remote media container service to copy
557     // package uri's from external media onto secure containers
558     // or internal storage.
559     private IMediaContainerService mContainerService = null;
560 
561     static final int SEND_PENDING_BROADCAST = 1;
562     static final int MCS_BOUND = 3;
563     static final int END_COPY = 4;
564     static final int INIT_COPY = 5;
565     static final int MCS_UNBIND = 6;
566     static final int START_CLEANING_PACKAGE = 7;
567     static final int FIND_INSTALL_LOC = 8;
568     static final int POST_INSTALL = 9;
569     static final int MCS_RECONNECT = 10;
570     static final int MCS_GIVE_UP = 11;
571     static final int UPDATED_MEDIA_STATUS = 12;
572     static final int WRITE_SETTINGS = 13;
573     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
574     static final int PACKAGE_VERIFIED = 15;
575     static final int CHECK_PENDING_VERIFICATION = 16;
576 
577     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
578 
579     // Delay time in millisecs
580     static final int BROADCAST_DELAY = 10 * 1000;
581 
582     static UserManagerService sUserManager;
583 
584     // Stores a list of users whose package restrictions file needs to be updated
585     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
586 
587     final private DefaultContainerConnection mDefContainerConn =
588             new DefaultContainerConnection();
589     class DefaultContainerConnection implements ServiceConnection {
onServiceConnected(ComponentName name, IBinder service)590         public void onServiceConnected(ComponentName name, IBinder service) {
591             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
592             IMediaContainerService imcs =
593                 IMediaContainerService.Stub.asInterface(service);
594             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
595         }
596 
onServiceDisconnected(ComponentName name)597         public void onServiceDisconnected(ComponentName name) {
598             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
599         }
600     };
601 
602     // Recordkeeping of restore-after-install operations that are currently in flight
603     // between the Package Manager and the Backup Manager
604     class PostInstallData {
605         public InstallArgs args;
606         public PackageInstalledInfo res;
607 
PostInstallData(InstallArgs _a, PackageInstalledInfo _r)608         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
609             args = _a;
610             res = _r;
611         }
612     };
613     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
614     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
615 
616     private final String mRequiredVerifierPackage;
617 
618     private final PackageUsage mPackageUsage = new PackageUsage();
619 
620     private class PackageUsage {
621         private static final int WRITE_INTERVAL
622             = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
623 
624         private final Object mFileLock = new Object();
625         private final AtomicLong mLastWritten = new AtomicLong(0);
626         private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
627 
628         private boolean mIsHistoricalPackageUsageAvailable = true;
629 
isHistoricalPackageUsageAvailable()630         boolean isHistoricalPackageUsageAvailable() {
631             return mIsHistoricalPackageUsageAvailable;
632         }
633 
write(boolean force)634         void write(boolean force) {
635             if (force) {
636                 writeInternal();
637                 return;
638             }
639             if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
640                 && !DEBUG_DEXOPT) {
641                 return;
642             }
643             if (mBackgroundWriteRunning.compareAndSet(false, true)) {
644                 new Thread("PackageUsage_DiskWriter") {
645                     @Override
646                     public void run() {
647                         try {
648                             writeInternal();
649                         } finally {
650                             mBackgroundWriteRunning.set(false);
651                         }
652                     }
653                 }.start();
654             }
655         }
656 
writeInternal()657         private void writeInternal() {
658             synchronized (mPackages) {
659                 synchronized (mFileLock) {
660                     AtomicFile file = getFile();
661                     FileOutputStream f = null;
662                     try {
663                         f = file.startWrite();
664                         BufferedOutputStream out = new BufferedOutputStream(f);
665                         FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
666                         StringBuilder sb = new StringBuilder();
667                         for (PackageParser.Package pkg : mPackages.values()) {
668                             if (pkg.mLastPackageUsageTimeInMills == 0) {
669                                 continue;
670                             }
671                             sb.setLength(0);
672                             sb.append(pkg.packageName);
673                             sb.append(' ');
674                             sb.append((long)pkg.mLastPackageUsageTimeInMills);
675                             sb.append('\n');
676                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
677                         }
678                         out.flush();
679                         file.finishWrite(f);
680                     } catch (IOException e) {
681                         if (f != null) {
682                             file.failWrite(f);
683                         }
684                         Log.e(TAG, "Failed to write package usage times", e);
685                     }
686                 }
687             }
688             mLastWritten.set(SystemClock.elapsedRealtime());
689         }
690 
readLP()691         void readLP() {
692             synchronized (mFileLock) {
693                 AtomicFile file = getFile();
694                 BufferedInputStream in = null;
695                 try {
696                     in = new BufferedInputStream(file.openRead());
697                     StringBuffer sb = new StringBuffer();
698                     while (true) {
699                         String packageName = readToken(in, sb, ' ');
700                         if (packageName == null) {
701                             break;
702                         }
703                         String timeInMillisString = readToken(in, sb, '\n');
704                         if (timeInMillisString == null) {
705                             throw new IOException("Failed to find last usage time for package "
706                                                   + packageName);
707                         }
708                         PackageParser.Package pkg = mPackages.get(packageName);
709                         if (pkg == null) {
710                             continue;
711                         }
712                         long timeInMillis;
713                         try {
714                             timeInMillis = Long.parseLong(timeInMillisString.toString());
715                         } catch (NumberFormatException e) {
716                             throw new IOException("Failed to parse " + timeInMillisString
717                                                   + " as a long.", e);
718                         }
719                         pkg.mLastPackageUsageTimeInMills = timeInMillis;
720                     }
721                 } catch (FileNotFoundException expected) {
722                     mIsHistoricalPackageUsageAvailable = false;
723                 } catch (IOException e) {
724                     Log.w(TAG, "Failed to read package usage times", e);
725                 } finally {
726                     IoUtils.closeQuietly(in);
727                 }
728             }
729             mLastWritten.set(SystemClock.elapsedRealtime());
730         }
731 
readToken(InputStream in, StringBuffer sb, char endOfToken)732         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
733                 throws IOException {
734             sb.setLength(0);
735             while (true) {
736                 int ch = in.read();
737                 if (ch == -1) {
738                     if (sb.length() == 0) {
739                         return null;
740                     }
741                     throw new IOException("Unexpected EOF");
742                 }
743                 if (ch == endOfToken) {
744                     return sb.toString();
745                 }
746                 sb.append((char)ch);
747             }
748         }
749 
getFile()750         private AtomicFile getFile() {
751             File dataDir = Environment.getDataDirectory();
752             File systemDir = new File(dataDir, "system");
753             File fname = new File(systemDir, "package-usage.list");
754             return new AtomicFile(fname);
755         }
756     }
757 
758     class PackageHandler extends Handler {
759         private boolean mBound = false;
760         final ArrayList<HandlerParams> mPendingInstalls =
761             new ArrayList<HandlerParams>();
762 
connectToService()763         private boolean connectToService() {
764             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
765                     " DefaultContainerService");
766             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
767             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
768             if (mContext.bindServiceAsUser(service, mDefContainerConn,
769                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
770                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
771                 mBound = true;
772                 return true;
773             }
774             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
775             return false;
776         }
777 
disconnectService()778         private void disconnectService() {
779             mContainerService = null;
780             mBound = false;
781             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
782             mContext.unbindService(mDefContainerConn);
783             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
784         }
785 
PackageHandler(Looper looper)786         PackageHandler(Looper looper) {
787             super(looper);
788         }
789 
handleMessage(Message msg)790         public void handleMessage(Message msg) {
791             try {
792                 doHandleMessage(msg);
793             } finally {
794                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
795             }
796         }
797 
doHandleMessage(Message msg)798         void doHandleMessage(Message msg) {
799             switch (msg.what) {
800                 case INIT_COPY: {
801                     HandlerParams params = (HandlerParams) msg.obj;
802                     int idx = mPendingInstalls.size();
803                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
804                     // If a bind was already initiated we dont really
805                     // need to do anything. The pending install
806                     // will be processed later on.
807                     if (!mBound) {
808                         // If this is the only one pending we might
809                         // have to bind to the service again.
810                         if (!connectToService()) {
811                             Slog.e(TAG, "Failed to bind to media container service");
812                             params.serviceError();
813                             return;
814                         } else {
815                             // Once we bind to the service, the first
816                             // pending request will be processed.
817                             mPendingInstalls.add(idx, params);
818                         }
819                     } else {
820                         mPendingInstalls.add(idx, params);
821                         // Already bound to the service. Just make
822                         // sure we trigger off processing the first request.
823                         if (idx == 0) {
824                             mHandler.sendEmptyMessage(MCS_BOUND);
825                         }
826                     }
827                     break;
828                 }
829                 case MCS_BOUND: {
830                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
831                     if (msg.obj != null) {
832                         mContainerService = (IMediaContainerService) msg.obj;
833                     }
834                     if (mContainerService == null) {
835                         // Something seriously wrong. Bail out
836                         Slog.e(TAG, "Cannot bind to media container service");
837                         for (HandlerParams params : mPendingInstalls) {
838                             // Indicate service bind error
839                             params.serviceError();
840                         }
841                         mPendingInstalls.clear();
842                     } else if (mPendingInstalls.size() > 0) {
843                         HandlerParams params = mPendingInstalls.get(0);
844                         if (params != null) {
845                             if (params.startCopy()) {
846                                 // We are done...  look for more work or to
847                                 // go idle.
848                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
849                                         "Checking for more work or unbind...");
850                                 // Delete pending install
851                                 if (mPendingInstalls.size() > 0) {
852                                     mPendingInstalls.remove(0);
853                                 }
854                                 if (mPendingInstalls.size() == 0) {
855                                     if (mBound) {
856                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
857                                                 "Posting delayed MCS_UNBIND");
858                                         removeMessages(MCS_UNBIND);
859                                         Message ubmsg = obtainMessage(MCS_UNBIND);
860                                         // Unbind after a little delay, to avoid
861                                         // continual thrashing.
862                                         sendMessageDelayed(ubmsg, 10000);
863                                     }
864                                 } else {
865                                     // There are more pending requests in queue.
866                                     // Just post MCS_BOUND message to trigger processing
867                                     // of next pending install.
868                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
869                                             "Posting MCS_BOUND for next work");
870                                     mHandler.sendEmptyMessage(MCS_BOUND);
871                                 }
872                             }
873                         }
874                     } else {
875                         // Should never happen ideally.
876                         Slog.w(TAG, "Empty queue");
877                     }
878                     break;
879                 }
880                 case MCS_RECONNECT: {
881                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
882                     if (mPendingInstalls.size() > 0) {
883                         if (mBound) {
884                             disconnectService();
885                         }
886                         if (!connectToService()) {
887                             Slog.e(TAG, "Failed to bind to media container service");
888                             for (HandlerParams params : mPendingInstalls) {
889                                 // Indicate service bind error
890                                 params.serviceError();
891                             }
892                             mPendingInstalls.clear();
893                         }
894                     }
895                     break;
896                 }
897                 case MCS_UNBIND: {
898                     // If there is no actual work left, then time to unbind.
899                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
900 
901                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
902                         if (mBound) {
903                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
904 
905                             disconnectService();
906                         }
907                     } else if (mPendingInstalls.size() > 0) {
908                         // There are more pending requests in queue.
909                         // Just post MCS_BOUND message to trigger processing
910                         // of next pending install.
911                         mHandler.sendEmptyMessage(MCS_BOUND);
912                     }
913 
914                     break;
915                 }
916                 case MCS_GIVE_UP: {
917                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
918                     mPendingInstalls.remove(0);
919                     break;
920                 }
921                 case SEND_PENDING_BROADCAST: {
922                     String packages[];
923                     ArrayList<String> components[];
924                     int size = 0;
925                     int uids[];
926                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
927                     synchronized (mPackages) {
928                         if (mPendingBroadcasts == null) {
929                             return;
930                         }
931                         size = mPendingBroadcasts.size();
932                         if (size <= 0) {
933                             // Nothing to be done. Just return
934                             return;
935                         }
936                         packages = new String[size];
937                         components = new ArrayList[size];
938                         uids = new int[size];
939                         int i = 0;  // filling out the above arrays
940 
941                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
942                             int packageUserId = mPendingBroadcasts.userIdAt(n);
943                             Iterator<Map.Entry<String, ArrayList<String>>> it
944                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
945                                             .entrySet().iterator();
946                             while (it.hasNext() && i < size) {
947                                 Map.Entry<String, ArrayList<String>> ent = it.next();
948                                 packages[i] = ent.getKey();
949                                 components[i] = ent.getValue();
950                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
951                                 uids[i] = (ps != null)
952                                         ? UserHandle.getUid(packageUserId, ps.appId)
953                                         : -1;
954                                 i++;
955                             }
956                         }
957                         size = i;
958                         mPendingBroadcasts.clear();
959                     }
960                     // Send broadcasts
961                     for (int i = 0; i < size; i++) {
962                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
963                     }
964                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
965                     break;
966                 }
967                 case START_CLEANING_PACKAGE: {
968                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
969                     final String packageName = (String)msg.obj;
970                     final int userId = msg.arg1;
971                     final boolean andCode = msg.arg2 != 0;
972                     synchronized (mPackages) {
973                         if (userId == UserHandle.USER_ALL) {
974                             int[] users = sUserManager.getUserIds();
975                             for (int user : users) {
976                                 mSettings.addPackageToCleanLPw(
977                                         new PackageCleanItem(user, packageName, andCode));
978                             }
979                         } else {
980                             mSettings.addPackageToCleanLPw(
981                                     new PackageCleanItem(userId, packageName, andCode));
982                         }
983                     }
984                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
985                     startCleaningPackages();
986                 } break;
987                 case POST_INSTALL: {
988                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
989                     PostInstallData data = mRunningInstalls.get(msg.arg1);
990                     mRunningInstalls.delete(msg.arg1);
991                     boolean deleteOld = false;
992 
993                     if (data != null) {
994                         InstallArgs args = data.args;
995                         PackageInstalledInfo res = data.res;
996 
997                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
998                             res.removedInfo.sendBroadcast(false, true, false);
999                             Bundle extras = new Bundle(1);
1000                             extras.putInt(Intent.EXTRA_UID, res.uid);
1001                             // Determine the set of users who are adding this
1002                             // package for the first time vs. those who are seeing
1003                             // an update.
1004                             int[] firstUsers;
1005                             int[] updateUsers = new int[0];
1006                             if (res.origUsers == null || res.origUsers.length == 0) {
1007                                 firstUsers = res.newUsers;
1008                             } else {
1009                                 firstUsers = new int[0];
1010                                 for (int i=0; i<res.newUsers.length; i++) {
1011                                     int user = res.newUsers[i];
1012                                     boolean isNew = true;
1013                                     for (int j=0; j<res.origUsers.length; j++) {
1014                                         if (res.origUsers[j] == user) {
1015                                             isNew = false;
1016                                             break;
1017                                         }
1018                                     }
1019                                     if (isNew) {
1020                                         int[] newFirst = new int[firstUsers.length+1];
1021                                         System.arraycopy(firstUsers, 0, newFirst, 0,
1022                                                 firstUsers.length);
1023                                         newFirst[firstUsers.length] = user;
1024                                         firstUsers = newFirst;
1025                                     } else {
1026                                         int[] newUpdate = new int[updateUsers.length+1];
1027                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
1028                                                 updateUsers.length);
1029                                         newUpdate[updateUsers.length] = user;
1030                                         updateUsers = newUpdate;
1031                                     }
1032                                 }
1033                             }
1034                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1035                                     res.pkg.applicationInfo.packageName,
1036                                     extras, null, null, firstUsers);
1037                             final boolean update = res.removedInfo.removedPackage != null;
1038                             if (update) {
1039                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1040                             }
1041                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1042                                     res.pkg.applicationInfo.packageName,
1043                                     extras, null, null, updateUsers);
1044                             if (update) {
1045                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1046                                         res.pkg.applicationInfo.packageName,
1047                                         extras, null, null, updateUsers);
1048                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1049                                         null, null,
1050                                         res.pkg.applicationInfo.packageName, null, updateUsers);
1051 
1052                                 // treat asec-hosted packages like removable media on upgrade
1053                                 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
1054                                     if (DEBUG_INSTALL) {
1055                                         Slog.i(TAG, "upgrading pkg " + res.pkg
1056                                                 + " is ASEC-hosted -> AVAILABLE");
1057                                     }
1058                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1059                                     ArrayList<String> pkgList = new ArrayList<String>(1);
1060                                     pkgList.add(res.pkg.applicationInfo.packageName);
1061                                     sendResourcesChangedBroadcast(true, true,
1062                                             pkgList,uidArray, null);
1063                                 }
1064                             }
1065                             if (res.removedInfo.args != null) {
1066                                 // Remove the replaced package's older resources safely now
1067                                 deleteOld = true;
1068                             }
1069 
1070                             // Log current value of "unknown sources" setting
1071                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1072                                 getUnknownSourcesSettings());
1073                         }
1074                         // Force a gc to clear up things
1075                         Runtime.getRuntime().gc();
1076                         // We delete after a gc for applications  on sdcard.
1077                         if (deleteOld) {
1078                             synchronized (mInstallLock) {
1079                                 res.removedInfo.args.doPostDeleteLI(true);
1080                             }
1081                         }
1082                         if (args.observer != null) {
1083                             try {
1084                                 Bundle extras = extrasForInstallResult(res);
1085                                 args.observer.onPackageInstalled(res.name, res.returnCode,
1086                                         res.returnMsg, extras);
1087                             } catch (RemoteException e) {
1088                                 Slog.i(TAG, "Observer no longer exists.");
1089                             }
1090                         }
1091                     } else {
1092                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1093                     }
1094                 } break;
1095                 case UPDATED_MEDIA_STATUS: {
1096                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1097                     boolean reportStatus = msg.arg1 == 1;
1098                     boolean doGc = msg.arg2 == 1;
1099                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1100                     if (doGc) {
1101                         // Force a gc to clear up stale containers.
1102                         Runtime.getRuntime().gc();
1103                     }
1104                     if (msg.obj != null) {
1105                         @SuppressWarnings("unchecked")
1106                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1107                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1108                         // Unload containers
1109                         unloadAllContainers(args);
1110                     }
1111                     if (reportStatus) {
1112                         try {
1113                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1114                             PackageHelper.getMountService().finishMediaUpdate();
1115                         } catch (RemoteException e) {
1116                             Log.e(TAG, "MountService not running?");
1117                         }
1118                     }
1119                 } break;
1120                 case WRITE_SETTINGS: {
1121                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1122                     synchronized (mPackages) {
1123                         removeMessages(WRITE_SETTINGS);
1124                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1125                         mSettings.writeLPr();
1126                         mDirtyUsers.clear();
1127                     }
1128                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1129                 } break;
1130                 case WRITE_PACKAGE_RESTRICTIONS: {
1131                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1132                     synchronized (mPackages) {
1133                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1134                         for (int userId : mDirtyUsers) {
1135                             mSettings.writePackageRestrictionsLPr(userId);
1136                         }
1137                         mDirtyUsers.clear();
1138                     }
1139                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1140                 } break;
1141                 case CHECK_PENDING_VERIFICATION: {
1142                     final int verificationId = msg.arg1;
1143                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1144 
1145                     if ((state != null) && !state.timeoutExtended()) {
1146                         final InstallArgs args = state.getInstallArgs();
1147                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1148 
1149                         Slog.i(TAG, "Verification timed out for " + originUri);
1150                         mPendingVerification.remove(verificationId);
1151 
1152                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1153 
1154                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1155                             Slog.i(TAG, "Continuing with installation of " + originUri);
1156                             state.setVerifierResponse(Binder.getCallingUid(),
1157                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1158                             broadcastPackageVerified(verificationId, originUri,
1159                                     PackageManager.VERIFICATION_ALLOW,
1160                                     state.getInstallArgs().getUser());
1161                             try {
1162                                 ret = args.copyApk(mContainerService, true);
1163                             } catch (RemoteException e) {
1164                                 Slog.e(TAG, "Could not contact the ContainerService");
1165                             }
1166                         } else {
1167                             broadcastPackageVerified(verificationId, originUri,
1168                                     PackageManager.VERIFICATION_REJECT,
1169                                     state.getInstallArgs().getUser());
1170                         }
1171 
1172                         processPendingInstall(args, ret);
1173                         mHandler.sendEmptyMessage(MCS_UNBIND);
1174                     }
1175                     break;
1176                 }
1177                 case PACKAGE_VERIFIED: {
1178                     final int verificationId = msg.arg1;
1179 
1180                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1181                     if (state == null) {
1182                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1183                         break;
1184                     }
1185 
1186                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1187 
1188                     state.setVerifierResponse(response.callerUid, response.code);
1189 
1190                     if (state.isVerificationComplete()) {
1191                         mPendingVerification.remove(verificationId);
1192 
1193                         final InstallArgs args = state.getInstallArgs();
1194                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1195 
1196                         int ret;
1197                         if (state.isInstallAllowed()) {
1198                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1199                             broadcastPackageVerified(verificationId, originUri,
1200                                     response.code, state.getInstallArgs().getUser());
1201                             try {
1202                                 ret = args.copyApk(mContainerService, true);
1203                             } catch (RemoteException e) {
1204                                 Slog.e(TAG, "Could not contact the ContainerService");
1205                             }
1206                         } else {
1207                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1208                         }
1209 
1210                         processPendingInstall(args, ret);
1211 
1212                         mHandler.sendEmptyMessage(MCS_UNBIND);
1213                     }
1214 
1215                     break;
1216                 }
1217             }
1218         }
1219     }
1220 
extrasForInstallResult(PackageInstalledInfo res)1221     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1222         Bundle extras = null;
1223         switch (res.returnCode) {
1224             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1225                 extras = new Bundle();
1226                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1227                         res.origPermission);
1228                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1229                         res.origPackage);
1230                 break;
1231             }
1232         }
1233         return extras;
1234     }
1235 
scheduleWriteSettingsLocked()1236     void scheduleWriteSettingsLocked() {
1237         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1238             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1239         }
1240     }
1241 
scheduleWritePackageRestrictionsLocked(int userId)1242     void scheduleWritePackageRestrictionsLocked(int userId) {
1243         if (!sUserManager.exists(userId)) return;
1244         mDirtyUsers.add(userId);
1245         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1246             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1247         }
1248     }
1249 
main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1250     public static final PackageManagerService main(Context context, Installer installer,
1251             boolean factoryTest, boolean onlyCore) {
1252         PackageManagerService m = new PackageManagerService(context, installer,
1253                 factoryTest, onlyCore);
1254         ServiceManager.addService("package", m);
1255         return m;
1256     }
1257 
splitString(String str, char sep)1258     static String[] splitString(String str, char sep) {
1259         int count = 1;
1260         int i = 0;
1261         while ((i=str.indexOf(sep, i)) >= 0) {
1262             count++;
1263             i++;
1264         }
1265 
1266         String[] res = new String[count];
1267         i=0;
1268         count = 0;
1269         int lastI=0;
1270         while ((i=str.indexOf(sep, i)) >= 0) {
1271             res[count] = str.substring(lastI, i);
1272             count++;
1273             i++;
1274             lastI = i;
1275         }
1276         res[count] = str.substring(lastI, str.length());
1277         return res;
1278     }
1279 
getDefaultDisplayMetrics(Context context, DisplayMetrics metrics)1280     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1281         DisplayManager displayManager = (DisplayManager) context.getSystemService(
1282                 Context.DISPLAY_SERVICE);
1283         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1284     }
1285 
PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1286     public PackageManagerService(Context context, Installer installer,
1287             boolean factoryTest, boolean onlyCore) {
1288         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1289                 SystemClock.uptimeMillis());
1290 
1291         if (mSdkVersion <= 0) {
1292             Slog.w(TAG, "**** ro.build.version.sdk not set!");
1293         }
1294 
1295         mContext = context;
1296         mFactoryTest = factoryTest;
1297         mOnlyCore = onlyCore;
1298         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1299         mMetrics = new DisplayMetrics();
1300         mSettings = new Settings(context);
1301         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1302                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1303         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1304                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1305         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1306                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1307         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1308                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1309         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1310                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1311         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1312                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1313 
1314         // TODO: add a property to control this?
1315         long dexOptLRUThresholdInMinutes;
1316         if (mLazyDexOpt) {
1317             dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
1318         } else {
1319             dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
1320         }
1321         mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
1322 
1323         String separateProcesses = SystemProperties.get("debug.separate_processes");
1324         if (separateProcesses != null && separateProcesses.length() > 0) {
1325             if ("*".equals(separateProcesses)) {
1326                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1327                 mSeparateProcesses = null;
1328                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1329             } else {
1330                 mDefParseFlags = 0;
1331                 mSeparateProcesses = separateProcesses.split(",");
1332                 Slog.w(TAG, "Running with debug.separate_processes: "
1333                         + separateProcesses);
1334             }
1335         } else {
1336             mDefParseFlags = 0;
1337             mSeparateProcesses = null;
1338         }
1339 
1340         mInstaller = installer;
1341 
1342         getDefaultDisplayMetrics(context, mMetrics);
1343 
1344         SystemConfig systemConfig = SystemConfig.getInstance();
1345         mGlobalGids = systemConfig.getGlobalGids();
1346         mSystemPermissions = systemConfig.getSystemPermissions();
1347         mAvailableFeatures = systemConfig.getAvailableFeatures();
1348 
1349         synchronized (mInstallLock) {
1350         // writer
1351         synchronized (mPackages) {
1352             mHandlerThread = new ServiceThread(TAG,
1353                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1354             mHandlerThread.start();
1355             mHandler = new PackageHandler(mHandlerThread.getLooper());
1356             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1357 
1358             File dataDir = Environment.getDataDirectory();
1359             mAppDataDir = new File(dataDir, "data");
1360             mAppInstallDir = new File(dataDir, "app");
1361             mAppLib32InstallDir = new File(dataDir, "app-lib");
1362             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1363             mUserAppDataDir = new File(dataDir, "user");
1364             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1365 
1366             sUserManager = new UserManagerService(context, this,
1367                     mInstallLock, mPackages);
1368 
1369             // Propagate permission configuration in to package manager.
1370             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1371                     = systemConfig.getPermissions();
1372             for (int i=0; i<permConfig.size(); i++) {
1373                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1374                 BasePermission bp = mSettings.mPermissions.get(perm.name);
1375                 if (bp == null) {
1376                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1377                     mSettings.mPermissions.put(perm.name, bp);
1378                 }
1379                 if (perm.gids != null) {
1380                     bp.gids = appendInts(bp.gids, perm.gids);
1381                 }
1382             }
1383 
1384             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1385             for (int i=0; i<libConfig.size(); i++) {
1386                 mSharedLibraries.put(libConfig.keyAt(i),
1387                         new SharedLibraryEntry(libConfig.valueAt(i), null));
1388             }
1389 
1390             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1391 
1392             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1393                     mSdkVersion, mOnlyCore);
1394 
1395             String customResolverActivity = Resources.getSystem().getString(
1396                     R.string.config_customResolverActivity);
1397             if (TextUtils.isEmpty(customResolverActivity)) {
1398                 customResolverActivity = null;
1399             } else {
1400                 mCustomResolverComponentName = ComponentName.unflattenFromString(
1401                         customResolverActivity);
1402             }
1403 
1404             long startTime = SystemClock.uptimeMillis();
1405 
1406             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1407                     startTime);
1408 
1409             // Set flag to monitor and not change apk file paths when
1410             // scanning install directories.
1411             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1412 
1413             final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
1414 
1415             /**
1416              * Add everything in the in the boot class path to the
1417              * list of process files because dexopt will have been run
1418              * if necessary during zygote startup.
1419              */
1420             final String bootClassPath = System.getenv("BOOTCLASSPATH");
1421             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1422 
1423             if (bootClassPath != null) {
1424                 String[] bootClassPathElements = splitString(bootClassPath, ':');
1425                 for (String element : bootClassPathElements) {
1426                     alreadyDexOpted.add(element);
1427                 }
1428             } else {
1429                 Slog.w(TAG, "No BOOTCLASSPATH found!");
1430             }
1431 
1432             if (systemServerClassPath != null) {
1433                 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1434                 for (String element : systemServerClassPathElements) {
1435                     alreadyDexOpted.add(element);
1436                 }
1437             } else {
1438                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1439             }
1440 
1441             final List<String> allInstructionSets = getAllInstructionSets();
1442             final String[] dexCodeInstructionSets =
1443                 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
1444 
1445             /**
1446              * Ensure all external libraries have had dexopt run on them.
1447              */
1448             if (mSharedLibraries.size() > 0) {
1449                 // NOTE: For now, we're compiling these system "shared libraries"
1450                 // (and framework jars) into all available architectures. It's possible
1451                 // to compile them only when we come across an app that uses them (there's
1452                 // already logic for that in scanPackageLI) but that adds some complexity.
1453                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1454                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1455                         final String lib = libEntry.path;
1456                         if (lib == null) {
1457                             continue;
1458                         }
1459 
1460                         try {
1461                             byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
1462                                                                                  dexCodeInstructionSet,
1463                                                                                  false);
1464                             if (dexoptRequired != DexFile.UP_TO_DATE) {
1465                                 alreadyDexOpted.add(lib);
1466 
1467                                 // The list of "shared libraries" we have at this point is
1468                                 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1469                                     mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1470                                 } else {
1471                                     mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1472                                 }
1473                             }
1474                         } catch (FileNotFoundException e) {
1475                             Slog.w(TAG, "Library not found: " + lib);
1476                         } catch (IOException e) {
1477                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1478                                     + e.getMessage());
1479                         }
1480                     }
1481                 }
1482             }
1483 
1484             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1485 
1486             // Gross hack for now: we know this file doesn't contain any
1487             // code, so don't dexopt it to avoid the resulting log spew.
1488             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1489 
1490             // Gross hack for now: we know this file is only part of
1491             // the boot class path for art, so don't dexopt it to
1492             // avoid the resulting log spew.
1493             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1494 
1495             /**
1496              * And there are a number of commands implemented in Java, which
1497              * we currently need to do the dexopt on so that they can be
1498              * run from a non-root shell.
1499              */
1500             String[] frameworkFiles = frameworkDir.list();
1501             if (frameworkFiles != null) {
1502                 // TODO: We could compile these only for the most preferred ABI. We should
1503                 // first double check that the dex files for these commands are not referenced
1504                 // by other system apps.
1505                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1506                     for (int i=0; i<frameworkFiles.length; i++) {
1507                         File libPath = new File(frameworkDir, frameworkFiles[i]);
1508                         String path = libPath.getPath();
1509                         // Skip the file if we already did it.
1510                         if (alreadyDexOpted.contains(path)) {
1511                             continue;
1512                         }
1513                         // Skip the file if it is not a type we want to dexopt.
1514                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1515                             continue;
1516                         }
1517                         try {
1518                             byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
1519                                                                                  dexCodeInstructionSet,
1520                                                                                  false);
1521                             if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1522                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1523                             } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
1524                                 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1525                             }
1526                         } catch (FileNotFoundException e) {
1527                             Slog.w(TAG, "Jar not found: " + path);
1528                         } catch (IOException e) {
1529                             Slog.w(TAG, "Exception reading jar: " + path, e);
1530                         }
1531                     }
1532                 }
1533             }
1534 
1535             // Collect vendor overlay packages.
1536             // (Do this before scanning any apps.)
1537             // For security and version matching reason, only consider
1538             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1539             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1540             scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1541                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
1542 
1543             // Find base frameworks (resource packages without code).
1544             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1545                     | PackageParser.PARSE_IS_SYSTEM_DIR
1546                     | PackageParser.PARSE_IS_PRIVILEGED,
1547                     scanFlags | SCAN_NO_DEX, 0);
1548 
1549             // Collected privileged system packages.
1550             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1551             scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1552                     | PackageParser.PARSE_IS_SYSTEM_DIR
1553                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
1554 
1555             // Collect ordinary system packages.
1556             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
1557             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1558                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1559 
1560             // Collect all vendor packages.
1561             File vendorAppDir = new File("/vendor/app");
1562             try {
1563                 vendorAppDir = vendorAppDir.getCanonicalFile();
1564             } catch (IOException e) {
1565                 // failed to look up canonical path, continue with original one
1566             }
1567             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1568                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1569 
1570             // Collect all OEM packages.
1571             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
1572             scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1573                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1574 
1575             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1576             mInstaller.moveFiles();
1577 
1578             // Prune any system packages that no longer exist.
1579             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1580             final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
1581             if (!mOnlyCore) {
1582                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1583                 while (psit.hasNext()) {
1584                     PackageSetting ps = psit.next();
1585 
1586                     /*
1587                      * If this is not a system app, it can't be a
1588                      * disable system app.
1589                      */
1590                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1591                         continue;
1592                     }
1593 
1594                     /*
1595                      * If the package is scanned, it's not erased.
1596                      */
1597                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1598                     if (scannedPkg != null) {
1599                         /*
1600                          * If the system app is both scanned and in the
1601                          * disabled packages list, then it must have been
1602                          * added via OTA. Remove it from the currently
1603                          * scanned package so the previously user-installed
1604                          * application can be scanned.
1605                          */
1606                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1607                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
1608                                     + ps.name + "; removing system app.  Last known codePath="
1609                                     + ps.codePathString + ", installStatus=" + ps.installStatus
1610                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
1611                                     + scannedPkg.mVersionCode);
1612                             removePackageLI(ps, true);
1613                             expectingBetter.put(ps.name, ps.codePath);
1614                         }
1615 
1616                         continue;
1617                     }
1618 
1619                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1620                         psit.remove();
1621                         logCriticalInfo(Log.WARN, "System package " + ps.name
1622                                 + " no longer exists; wiping its data");
1623                         removeDataDirsLI(ps.name);
1624                     } else {
1625                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1626                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1627                             possiblyDeletedUpdatedSystemApps.add(ps.name);
1628                         }
1629                     }
1630                 }
1631             }
1632 
1633             //look for any incomplete package installations
1634             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1635             //clean up list
1636             for(int i = 0; i < deletePkgsList.size(); i++) {
1637                 //clean up here
1638                 cleanupInstallFailedPackage(deletePkgsList.get(i));
1639             }
1640             //delete tmp files
1641             deleteTempPackageFiles();
1642 
1643             // Remove any shared userIDs that have no associated packages
1644             mSettings.pruneSharedUsersLPw();
1645 
1646             if (!mOnlyCore) {
1647                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1648                         SystemClock.uptimeMillis());
1649                 scanDirLI(mAppInstallDir, 0, scanFlags, 0);
1650 
1651                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1652                         scanFlags, 0);
1653 
1654                 /**
1655                  * Remove disable package settings for any updated system
1656                  * apps that were removed via an OTA. If they're not a
1657                  * previously-updated app, remove them completely.
1658                  * Otherwise, just revoke their system-level permissions.
1659                  */
1660                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1661                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1662                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1663 
1664                     String msg;
1665                     if (deletedPkg == null) {
1666                         msg = "Updated system package " + deletedAppName
1667                                 + " no longer exists; wiping its data";
1668                         removeDataDirsLI(deletedAppName);
1669                     } else {
1670                         msg = "Updated system app + " + deletedAppName
1671                                 + " no longer present; removing system privileges for "
1672                                 + deletedAppName;
1673 
1674                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1675 
1676                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1677                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1678                     }
1679                     logCriticalInfo(Log.WARN, msg);
1680                 }
1681 
1682                 /**
1683                  * Make sure all system apps that we expected to appear on
1684                  * the userdata partition actually showed up. If they never
1685                  * appeared, crawl back and revive the system version.
1686                  */
1687                 for (int i = 0; i < expectingBetter.size(); i++) {
1688                     final String packageName = expectingBetter.keyAt(i);
1689                     if (!mPackages.containsKey(packageName)) {
1690                         final File scanFile = expectingBetter.valueAt(i);
1691 
1692                         logCriticalInfo(Log.WARN, "Expected better " + packageName
1693                                 + " but never showed up; reverting to system");
1694 
1695                         final int reparseFlags;
1696                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
1697                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1698                                     | PackageParser.PARSE_IS_SYSTEM_DIR
1699                                     | PackageParser.PARSE_IS_PRIVILEGED;
1700                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
1701                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1702                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1703                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
1704                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1705                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1706                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
1707                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1708                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1709                         } else {
1710                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
1711                             continue;
1712                         }
1713 
1714                         mSettings.enableSystemPackageLPw(packageName);
1715 
1716                         try {
1717                             scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
1718                         } catch (PackageManagerException e) {
1719                             Slog.e(TAG, "Failed to parse original system package: "
1720                                     + e.getMessage());
1721                         }
1722                     }
1723                 }
1724             }
1725 
1726             // Now that we know all of the shared libraries, update all clients to have
1727             // the correct library paths.
1728             updateAllSharedLibrariesLPw();
1729 
1730             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
1731                 // NOTE: We ignore potential failures here during a system scan (like
1732                 // the rest of the commands above) because there's precious little we
1733                 // can do about it. A settings error is reported, though.
1734                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
1735                         false /* force dexopt */, false /* defer dexopt */);
1736             }
1737 
1738             // Now that we know all the packages we are keeping,
1739             // read and update their last usage times.
1740             mPackageUsage.readLP();
1741 
1742             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1743                     SystemClock.uptimeMillis());
1744             Slog.i(TAG, "Time to scan packages: "
1745                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
1746                     + " seconds");
1747 
1748             // If the platform SDK has changed since the last time we booted,
1749             // we need to re-grant app permission to catch any new ones that
1750             // appear.  This is really a hack, and means that apps can in some
1751             // cases get permissions that the user didn't initially explicitly
1752             // allow...  it would be nice to have some better way to handle
1753             // this situation.
1754             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1755                     != mSdkVersion;
1756             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1757                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1758                     + "; regranting permissions for internal storage");
1759             mSettings.mInternalSdkPlatform = mSdkVersion;
1760 
1761             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1762                     | (regrantPermissions
1763                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1764                             : 0));
1765 
1766             // If this is the first boot, and it is a normal boot, then
1767             // we need to initialize the default preferred apps.
1768             if (!mRestoredSettings && !onlyCore) {
1769                 mSettings.readDefaultPreferredAppsLPw(this, 0);
1770             }
1771 
1772             // If this is first boot after an OTA, and a normal boot, then
1773             // we need to clear code cache directories.
1774             mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
1775             if (mIsUpgrade && !onlyCore) {
1776                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
1777                 for (String pkgName : mSettings.mPackages.keySet()) {
1778                     deleteCodeCacheDirsLI(pkgName);
1779                 }
1780                 mSettings.mFingerprint = Build.FINGERPRINT;
1781             }
1782 
1783             // All the changes are done during package scanning.
1784             mSettings.updateInternalDatabaseVersion();
1785 
1786             // can downgrade to reader
1787             mSettings.writeLPr();
1788 
1789             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1790                     SystemClock.uptimeMillis());
1791 
1792 
1793             mRequiredVerifierPackage = getRequiredVerifierLPr();
1794         } // synchronized (mPackages)
1795         } // synchronized (mInstallLock)
1796 
1797         mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
1798 
1799         // Now after opening every single application zip, make sure they
1800         // are all flushed.  Not really needed, but keeps things nice and
1801         // tidy.
1802         Runtime.getRuntime().gc();
1803     }
1804 
1805     @Override
isFirstBoot()1806     public boolean isFirstBoot() {
1807         return !mRestoredSettings;
1808     }
1809 
1810     @Override
isOnlyCoreApps()1811     public boolean isOnlyCoreApps() {
1812         return mOnlyCore;
1813     }
1814 
1815     @Override
isUpgrade()1816     public boolean isUpgrade() {
1817         return mIsUpgrade;
1818     }
1819 
getRequiredVerifierLPr()1820     private String getRequiredVerifierLPr() {
1821         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1822         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1823                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1824 
1825         String requiredVerifier = null;
1826 
1827         final int N = receivers.size();
1828         for (int i = 0; i < N; i++) {
1829             final ResolveInfo info = receivers.get(i);
1830 
1831             if (info.activityInfo == null) {
1832                 continue;
1833             }
1834 
1835             final String packageName = info.activityInfo.packageName;
1836 
1837             final PackageSetting ps = mSettings.mPackages.get(packageName);
1838             if (ps == null) {
1839                 continue;
1840             }
1841 
1842             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1843             if (!gp.grantedPermissions
1844                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1845                 continue;
1846             }
1847 
1848             if (requiredVerifier != null) {
1849                 throw new RuntimeException("There can be only one required verifier");
1850             }
1851 
1852             requiredVerifier = packageName;
1853         }
1854 
1855         return requiredVerifier;
1856     }
1857 
1858     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)1859     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1860             throws RemoteException {
1861         try {
1862             return super.onTransact(code, data, reply, flags);
1863         } catch (RuntimeException e) {
1864             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1865                 Slog.wtf(TAG, "Package Manager Crash", e);
1866             }
1867             throw e;
1868         }
1869     }
1870 
cleanupInstallFailedPackage(PackageSetting ps)1871     void cleanupInstallFailedPackage(PackageSetting ps) {
1872         logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
1873 
1874         removeDataDirsLI(ps.name);
1875         if (ps.codePath != null) {
1876             if (ps.codePath.isDirectory()) {
1877                 FileUtils.deleteContents(ps.codePath);
1878             }
1879             ps.codePath.delete();
1880         }
1881         if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
1882             if (ps.resourcePath.isDirectory()) {
1883                 FileUtils.deleteContents(ps.resourcePath);
1884             }
1885             ps.resourcePath.delete();
1886         }
1887         mSettings.removePackageLPw(ps.name);
1888     }
1889 
appendInts(int[] cur, int[] add)1890     static int[] appendInts(int[] cur, int[] add) {
1891         if (add == null) return cur;
1892         if (cur == null) return add;
1893         final int N = add.length;
1894         for (int i=0; i<N; i++) {
1895             cur = appendInt(cur, add[i]);
1896         }
1897         return cur;
1898     }
1899 
removeInts(int[] cur, int[] rem)1900     static int[] removeInts(int[] cur, int[] rem) {
1901         if (rem == null) return cur;
1902         if (cur == null) return cur;
1903         final int N = rem.length;
1904         for (int i=0; i<N; i++) {
1905             cur = removeInt(cur, rem[i]);
1906         }
1907         return cur;
1908     }
1909 
generatePackageInfo(PackageParser.Package p, int flags, int userId)1910     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1911         if (!sUserManager.exists(userId)) return null;
1912         final PackageSetting ps = (PackageSetting) p.mExtras;
1913         if (ps == null) {
1914             return null;
1915         }
1916         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1917         final PackageUserState state = ps.readUserState(userId);
1918         return PackageParser.generatePackageInfo(p, gp.gids, flags,
1919                 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1920                 state, userId);
1921     }
1922 
1923     @Override
isPackageAvailable(String packageName, int userId)1924     public boolean isPackageAvailable(String packageName, int userId) {
1925         if (!sUserManager.exists(userId)) return false;
1926         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
1927         synchronized (mPackages) {
1928             PackageParser.Package p = mPackages.get(packageName);
1929             if (p != null) {
1930                 final PackageSetting ps = (PackageSetting) p.mExtras;
1931                 if (ps != null) {
1932                     final PackageUserState state = ps.readUserState(userId);
1933                     if (state != null) {
1934                         return PackageParser.isAvailable(state);
1935                     }
1936                 }
1937             }
1938         }
1939         return false;
1940     }
1941 
1942     @Override
getPackageInfo(String packageName, int flags, int userId)1943     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1944         if (!sUserManager.exists(userId)) return null;
1945         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
1946         // reader
1947         synchronized (mPackages) {
1948             PackageParser.Package p = mPackages.get(packageName);
1949             if (DEBUG_PACKAGE_INFO)
1950                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1951             if (p != null) {
1952                 return generatePackageInfo(p, flags, userId);
1953             }
1954             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1955                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1956             }
1957         }
1958         return null;
1959     }
1960 
1961     @Override
currentToCanonicalPackageNames(String[] names)1962     public String[] currentToCanonicalPackageNames(String[] names) {
1963         String[] out = new String[names.length];
1964         // reader
1965         synchronized (mPackages) {
1966             for (int i=names.length-1; i>=0; i--) {
1967                 PackageSetting ps = mSettings.mPackages.get(names[i]);
1968                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1969             }
1970         }
1971         return out;
1972     }
1973 
1974     @Override
canonicalToCurrentPackageNames(String[] names)1975     public String[] canonicalToCurrentPackageNames(String[] names) {
1976         String[] out = new String[names.length];
1977         // reader
1978         synchronized (mPackages) {
1979             for (int i=names.length-1; i>=0; i--) {
1980                 String cur = mSettings.mRenamedPackages.get(names[i]);
1981                 out[i] = cur != null ? cur : names[i];
1982             }
1983         }
1984         return out;
1985     }
1986 
1987     @Override
getPackageUid(String packageName, int userId)1988     public int getPackageUid(String packageName, int userId) {
1989         if (!sUserManager.exists(userId)) return -1;
1990         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
1991         // reader
1992         synchronized (mPackages) {
1993             PackageParser.Package p = mPackages.get(packageName);
1994             if(p != null) {
1995                 return UserHandle.getUid(userId, p.applicationInfo.uid);
1996             }
1997             PackageSetting ps = mSettings.mPackages.get(packageName);
1998             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1999                 return -1;
2000             }
2001             p = ps.pkg;
2002             return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
2003         }
2004     }
2005 
2006     @Override
getPackageGids(String packageName)2007     public int[] getPackageGids(String packageName) {
2008         // reader
2009         synchronized (mPackages) {
2010             PackageParser.Package p = mPackages.get(packageName);
2011             if (DEBUG_PACKAGE_INFO)
2012                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
2013             if (p != null) {
2014                 final PackageSetting ps = (PackageSetting)p.mExtras;
2015                 return ps.getGids();
2016             }
2017         }
2018         // stupid thing to indicate an error.
2019         return new int[0];
2020     }
2021 
generatePermissionInfo( BasePermission bp, int flags)2022     static final PermissionInfo generatePermissionInfo(
2023             BasePermission bp, int flags) {
2024         if (bp.perm != null) {
2025             return PackageParser.generatePermissionInfo(bp.perm, flags);
2026         }
2027         PermissionInfo pi = new PermissionInfo();
2028         pi.name = bp.name;
2029         pi.packageName = bp.sourcePackage;
2030         pi.nonLocalizedLabel = bp.name;
2031         pi.protectionLevel = bp.protectionLevel;
2032         return pi;
2033     }
2034 
2035     @Override
getPermissionInfo(String name, int flags)2036     public PermissionInfo getPermissionInfo(String name, int flags) {
2037         // reader
2038         synchronized (mPackages) {
2039             final BasePermission p = mSettings.mPermissions.get(name);
2040             if (p != null) {
2041                 return generatePermissionInfo(p, flags);
2042             }
2043             return null;
2044         }
2045     }
2046 
2047     @Override
queryPermissionsByGroup(String group, int flags)2048     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2049         // reader
2050         synchronized (mPackages) {
2051             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2052             for (BasePermission p : mSettings.mPermissions.values()) {
2053                 if (group == null) {
2054                     if (p.perm == null || p.perm.info.group == null) {
2055                         out.add(generatePermissionInfo(p, flags));
2056                     }
2057                 } else {
2058                     if (p.perm != null && group.equals(p.perm.info.group)) {
2059                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2060                     }
2061                 }
2062             }
2063 
2064             if (out.size() > 0) {
2065                 return out;
2066             }
2067             return mPermissionGroups.containsKey(group) ? out : null;
2068         }
2069     }
2070 
2071     @Override
getPermissionGroupInfo(String name, int flags)2072     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2073         // reader
2074         synchronized (mPackages) {
2075             return PackageParser.generatePermissionGroupInfo(
2076                     mPermissionGroups.get(name), flags);
2077         }
2078     }
2079 
2080     @Override
getAllPermissionGroups(int flags)2081     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2082         // reader
2083         synchronized (mPackages) {
2084             final int N = mPermissionGroups.size();
2085             ArrayList<PermissionGroupInfo> out
2086                     = new ArrayList<PermissionGroupInfo>(N);
2087             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2088                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2089             }
2090             return out;
2091         }
2092     }
2093 
generateApplicationInfoFromSettingsLPw(String packageName, int flags, int userId)2094     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2095             int userId) {
2096         if (!sUserManager.exists(userId)) return null;
2097         PackageSetting ps = mSettings.mPackages.get(packageName);
2098         if (ps != null) {
2099             if (ps.pkg == null) {
2100                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2101                         flags, userId);
2102                 if (pInfo != null) {
2103                     return pInfo.applicationInfo;
2104                 }
2105                 return null;
2106             }
2107             return PackageParser.generateApplicationInfo(ps.pkg, flags,
2108                     ps.readUserState(userId), userId);
2109         }
2110         return null;
2111     }
2112 
generatePackageInfoFromSettingsLPw(String packageName, int flags, int userId)2113     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2114             int userId) {
2115         if (!sUserManager.exists(userId)) return null;
2116         PackageSetting ps = mSettings.mPackages.get(packageName);
2117         if (ps != null) {
2118             PackageParser.Package pkg = ps.pkg;
2119             if (pkg == null) {
2120                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2121                     return null;
2122                 }
2123                 // Only data remains, so we aren't worried about code paths
2124                 pkg = new PackageParser.Package(packageName);
2125                 pkg.applicationInfo.packageName = packageName;
2126                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2127                 pkg.applicationInfo.dataDir =
2128                         getDataPathForPackage(packageName, 0).getPath();
2129                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2130                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2131             }
2132             return generatePackageInfo(pkg, flags, userId);
2133         }
2134         return null;
2135     }
2136 
2137     @Override
getApplicationInfo(String packageName, int flags, int userId)2138     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2139         if (!sUserManager.exists(userId)) return null;
2140         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2141         // writer
2142         synchronized (mPackages) {
2143             PackageParser.Package p = mPackages.get(packageName);
2144             if (DEBUG_PACKAGE_INFO) Log.v(
2145                     TAG, "getApplicationInfo " + packageName
2146                     + ": " + p);
2147             if (p != null) {
2148                 PackageSetting ps = mSettings.mPackages.get(packageName);
2149                 if (ps == null) return null;
2150                 // Note: isEnabledLP() does not apply here - always return info
2151                 return PackageParser.generateApplicationInfo(
2152                         p, flags, ps.readUserState(userId), userId);
2153             }
2154             if ("android".equals(packageName)||"system".equals(packageName)) {
2155                 return mAndroidApplication;
2156             }
2157             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2158                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2159             }
2160         }
2161         return null;
2162     }
2163 
2164 
2165     @Override
freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer)2166     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
2167         mContext.enforceCallingOrSelfPermission(
2168                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2169         // Queue up an async operation since clearing cache may take a little while.
2170         mHandler.post(new Runnable() {
2171             public void run() {
2172                 mHandler.removeCallbacks(this);
2173                 int retCode = -1;
2174                 synchronized (mInstallLock) {
2175                     retCode = mInstaller.freeCache(freeStorageSize);
2176                     if (retCode < 0) {
2177                         Slog.w(TAG, "Couldn't clear application caches");
2178                     }
2179                 }
2180                 if (observer != null) {
2181                     try {
2182                         observer.onRemoveCompleted(null, (retCode >= 0));
2183                     } catch (RemoteException e) {
2184                         Slog.w(TAG, "RemoveException when invoking call back");
2185                     }
2186                 }
2187             }
2188         });
2189     }
2190 
2191     @Override
freeStorage(final long freeStorageSize, final IntentSender pi)2192     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
2193         mContext.enforceCallingOrSelfPermission(
2194                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2195         // Queue up an async operation since clearing cache may take a little while.
2196         mHandler.post(new Runnable() {
2197             public void run() {
2198                 mHandler.removeCallbacks(this);
2199                 int retCode = -1;
2200                 synchronized (mInstallLock) {
2201                     retCode = mInstaller.freeCache(freeStorageSize);
2202                     if (retCode < 0) {
2203                         Slog.w(TAG, "Couldn't clear application caches");
2204                     }
2205                 }
2206                 if(pi != null) {
2207                     try {
2208                         // Callback via pending intent
2209                         int code = (retCode >= 0) ? 1 : 0;
2210                         pi.sendIntent(null, code, null,
2211                                 null, null);
2212                     } catch (SendIntentException e1) {
2213                         Slog.i(TAG, "Failed to send pending intent");
2214                     }
2215                 }
2216             }
2217         });
2218     }
2219 
freeStorage(long freeStorageSize)2220     void freeStorage(long freeStorageSize) throws IOException {
2221         synchronized (mInstallLock) {
2222             if (mInstaller.freeCache(freeStorageSize) < 0) {
2223                 throw new IOException("Failed to free enough space");
2224             }
2225         }
2226     }
2227 
2228     @Override
getActivityInfo(ComponentName component, int flags, int userId)2229     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2230         if (!sUserManager.exists(userId)) return null;
2231         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
2232         synchronized (mPackages) {
2233             PackageParser.Activity a = mActivities.mActivities.get(component);
2234 
2235             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2236             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2237                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2238                 if (ps == null) return null;
2239                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2240                         userId);
2241             }
2242             if (mResolveComponentName.equals(component)) {
2243                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
2244                         new PackageUserState(), userId);
2245             }
2246         }
2247         return null;
2248     }
2249 
2250     @Override
activitySupportsIntent(ComponentName component, Intent intent, String resolvedType)2251     public boolean activitySupportsIntent(ComponentName component, Intent intent,
2252             String resolvedType) {
2253         synchronized (mPackages) {
2254             PackageParser.Activity a = mActivities.mActivities.get(component);
2255             if (a == null) {
2256                 return false;
2257             }
2258             for (int i=0; i<a.intents.size(); i++) {
2259                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2260                         intent.getData(), intent.getCategories(), TAG) >= 0) {
2261                     return true;
2262                 }
2263             }
2264             return false;
2265         }
2266     }
2267 
2268     @Override
getReceiverInfo(ComponentName component, int flags, int userId)2269     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2270         if (!sUserManager.exists(userId)) return null;
2271         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
2272         synchronized (mPackages) {
2273             PackageParser.Activity a = mReceivers.mActivities.get(component);
2274             if (DEBUG_PACKAGE_INFO) Log.v(
2275                 TAG, "getReceiverInfo " + component + ": " + a);
2276             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2277                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2278                 if (ps == null) return null;
2279                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2280                         userId);
2281             }
2282         }
2283         return null;
2284     }
2285 
2286     @Override
getServiceInfo(ComponentName component, int flags, int userId)2287     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2288         if (!sUserManager.exists(userId)) return null;
2289         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
2290         synchronized (mPackages) {
2291             PackageParser.Service s = mServices.mServices.get(component);
2292             if (DEBUG_PACKAGE_INFO) Log.v(
2293                 TAG, "getServiceInfo " + component + ": " + s);
2294             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2295                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2296                 if (ps == null) return null;
2297                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2298                         userId);
2299             }
2300         }
2301         return null;
2302     }
2303 
2304     @Override
getProviderInfo(ComponentName component, int flags, int userId)2305     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2306         if (!sUserManager.exists(userId)) return null;
2307         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
2308         synchronized (mPackages) {
2309             PackageParser.Provider p = mProviders.mProviders.get(component);
2310             if (DEBUG_PACKAGE_INFO) Log.v(
2311                 TAG, "getProviderInfo " + component + ": " + p);
2312             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2313                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2314                 if (ps == null) return null;
2315                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2316                         userId);
2317             }
2318         }
2319         return null;
2320     }
2321 
2322     @Override
getSystemSharedLibraryNames()2323     public String[] getSystemSharedLibraryNames() {
2324         Set<String> libSet;
2325         synchronized (mPackages) {
2326             libSet = mSharedLibraries.keySet();
2327             int size = libSet.size();
2328             if (size > 0) {
2329                 String[] libs = new String[size];
2330                 libSet.toArray(libs);
2331                 return libs;
2332             }
2333         }
2334         return null;
2335     }
2336 
2337     @Override
getSystemAvailableFeatures()2338     public FeatureInfo[] getSystemAvailableFeatures() {
2339         Collection<FeatureInfo> featSet;
2340         synchronized (mPackages) {
2341             featSet = mAvailableFeatures.values();
2342             int size = featSet.size();
2343             if (size > 0) {
2344                 FeatureInfo[] features = new FeatureInfo[size+1];
2345                 featSet.toArray(features);
2346                 FeatureInfo fi = new FeatureInfo();
2347                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2348                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
2349                 features[size] = fi;
2350                 return features;
2351             }
2352         }
2353         return null;
2354     }
2355 
2356     @Override
hasSystemFeature(String name)2357     public boolean hasSystemFeature(String name) {
2358         synchronized (mPackages) {
2359             return mAvailableFeatures.containsKey(name);
2360         }
2361     }
2362 
checkValidCaller(int uid, int userId)2363     private void checkValidCaller(int uid, int userId) {
2364         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2365             return;
2366 
2367         throw new SecurityException("Caller uid=" + uid
2368                 + " is not privileged to communicate with user=" + userId);
2369     }
2370 
2371     @Override
checkPermission(String permName, String pkgName)2372     public int checkPermission(String permName, String pkgName) {
2373         synchronized (mPackages) {
2374             PackageParser.Package p = mPackages.get(pkgName);
2375             if (p != null && p.mExtras != null) {
2376                 PackageSetting ps = (PackageSetting)p.mExtras;
2377                 if (ps.sharedUser != null) {
2378                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
2379                         return PackageManager.PERMISSION_GRANTED;
2380                     }
2381                 } else if (ps.grantedPermissions.contains(permName)) {
2382                     return PackageManager.PERMISSION_GRANTED;
2383                 }
2384             }
2385         }
2386         return PackageManager.PERMISSION_DENIED;
2387     }
2388 
2389     @Override
checkUidPermission(String permName, int uid)2390     public int checkUidPermission(String permName, int uid) {
2391         synchronized (mPackages) {
2392             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2393             if (obj != null) {
2394                 GrantedPermissions gp = (GrantedPermissions)obj;
2395                 if (gp.grantedPermissions.contains(permName)) {
2396                     return PackageManager.PERMISSION_GRANTED;
2397                 }
2398             } else {
2399                 ArraySet<String> perms = mSystemPermissions.get(uid);
2400                 if (perms != null && perms.contains(permName)) {
2401                     return PackageManager.PERMISSION_GRANTED;
2402                 }
2403             }
2404         }
2405         return PackageManager.PERMISSION_DENIED;
2406     }
2407 
2408     /**
2409      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2410      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2411      * @param checkShell TODO(yamasani):
2412      * @param message the message to log on security exception
2413      */
enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message)2414     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
2415             boolean checkShell, String message) {
2416         if (userId < 0) {
2417             throw new IllegalArgumentException("Invalid userId " + userId);
2418         }
2419         if (checkShell) {
2420             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2421         }
2422         if (userId == UserHandle.getUserId(callingUid)) return;
2423         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2424             if (requireFullPermission) {
2425                 mContext.enforceCallingOrSelfPermission(
2426                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2427             } else {
2428                 try {
2429                     mContext.enforceCallingOrSelfPermission(
2430                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2431                 } catch (SecurityException se) {
2432                     mContext.enforceCallingOrSelfPermission(
2433                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2434                 }
2435             }
2436         }
2437     }
2438 
enforceShellRestriction(String restriction, int callingUid, int userHandle)2439     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
2440         if (callingUid == Process.SHELL_UID) {
2441             if (userHandle >= 0
2442                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
2443                 throw new SecurityException("Shell does not have permission to access user "
2444                         + userHandle);
2445             } else if (userHandle < 0) {
2446                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
2447                         + Debug.getCallers(3));
2448             }
2449         }
2450     }
2451 
findPermissionTreeLP(String permName)2452     private BasePermission findPermissionTreeLP(String permName) {
2453         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2454             if (permName.startsWith(bp.name) &&
2455                     permName.length() > bp.name.length() &&
2456                     permName.charAt(bp.name.length()) == '.') {
2457                 return bp;
2458             }
2459         }
2460         return null;
2461     }
2462 
checkPermissionTreeLP(String permName)2463     private BasePermission checkPermissionTreeLP(String permName) {
2464         if (permName != null) {
2465             BasePermission bp = findPermissionTreeLP(permName);
2466             if (bp != null) {
2467                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2468                     return bp;
2469                 }
2470                 throw new SecurityException("Calling uid "
2471                         + Binder.getCallingUid()
2472                         + " is not allowed to add to permission tree "
2473                         + bp.name + " owned by uid " + bp.uid);
2474             }
2475         }
2476         throw new SecurityException("No permission tree found for " + permName);
2477     }
2478 
compareStrings(CharSequence s1, CharSequence s2)2479     static boolean compareStrings(CharSequence s1, CharSequence s2) {
2480         if (s1 == null) {
2481             return s2 == null;
2482         }
2483         if (s2 == null) {
2484             return false;
2485         }
2486         if (s1.getClass() != s2.getClass()) {
2487             return false;
2488         }
2489         return s1.equals(s2);
2490     }
2491 
comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2)2492     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2493         if (pi1.icon != pi2.icon) return false;
2494         if (pi1.logo != pi2.logo) return false;
2495         if (pi1.protectionLevel != pi2.protectionLevel) return false;
2496         if (!compareStrings(pi1.name, pi2.name)) return false;
2497         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2498         // We'll take care of setting this one.
2499         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2500         // These are not currently stored in settings.
2501         //if (!compareStrings(pi1.group, pi2.group)) return false;
2502         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2503         //if (pi1.labelRes != pi2.labelRes) return false;
2504         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2505         return true;
2506     }
2507 
permissionInfoFootprint(PermissionInfo info)2508     int permissionInfoFootprint(PermissionInfo info) {
2509         int size = info.name.length();
2510         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
2511         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
2512         return size;
2513     }
2514 
calculateCurrentPermissionFootprintLocked(BasePermission tree)2515     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2516         int size = 0;
2517         for (BasePermission perm : mSettings.mPermissions.values()) {
2518             if (perm.uid == tree.uid) {
2519                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
2520             }
2521         }
2522         return size;
2523     }
2524 
enforcePermissionCapLocked(PermissionInfo info, BasePermission tree)2525     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2526         // We calculate the max size of permissions defined by this uid and throw
2527         // if that plus the size of 'info' would exceed our stated maximum.
2528         if (tree.uid != Process.SYSTEM_UID) {
2529             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2530             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
2531                 throw new SecurityException("Permission tree size cap exceeded");
2532             }
2533         }
2534     }
2535 
addPermissionLocked(PermissionInfo info, boolean async)2536     boolean addPermissionLocked(PermissionInfo info, boolean async) {
2537         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2538             throw new SecurityException("Label must be specified in permission");
2539         }
2540         BasePermission tree = checkPermissionTreeLP(info.name);
2541         BasePermission bp = mSettings.mPermissions.get(info.name);
2542         boolean added = bp == null;
2543         boolean changed = true;
2544         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2545         if (added) {
2546             enforcePermissionCapLocked(info, tree);
2547             bp = new BasePermission(info.name, tree.sourcePackage,
2548                     BasePermission.TYPE_DYNAMIC);
2549         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2550             throw new SecurityException(
2551                     "Not allowed to modify non-dynamic permission "
2552                     + info.name);
2553         } else {
2554             if (bp.protectionLevel == fixedLevel
2555                     && bp.perm.owner.equals(tree.perm.owner)
2556                     && bp.uid == tree.uid
2557                     && comparePermissionInfos(bp.perm.info, info)) {
2558                 changed = false;
2559             }
2560         }
2561         bp.protectionLevel = fixedLevel;
2562         info = new PermissionInfo(info);
2563         info.protectionLevel = fixedLevel;
2564         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2565         bp.perm.info.packageName = tree.perm.info.packageName;
2566         bp.uid = tree.uid;
2567         if (added) {
2568             mSettings.mPermissions.put(info.name, bp);
2569         }
2570         if (changed) {
2571             if (!async) {
2572                 mSettings.writeLPr();
2573             } else {
2574                 scheduleWriteSettingsLocked();
2575             }
2576         }
2577         return added;
2578     }
2579 
2580     @Override
addPermission(PermissionInfo info)2581     public boolean addPermission(PermissionInfo info) {
2582         synchronized (mPackages) {
2583             return addPermissionLocked(info, false);
2584         }
2585     }
2586 
2587     @Override
addPermissionAsync(PermissionInfo info)2588     public boolean addPermissionAsync(PermissionInfo info) {
2589         synchronized (mPackages) {
2590             return addPermissionLocked(info, true);
2591         }
2592     }
2593 
2594     @Override
removePermission(String name)2595     public void removePermission(String name) {
2596         synchronized (mPackages) {
2597             checkPermissionTreeLP(name);
2598             BasePermission bp = mSettings.mPermissions.get(name);
2599             if (bp != null) {
2600                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2601                     throw new SecurityException(
2602                             "Not allowed to modify non-dynamic permission "
2603                             + name);
2604                 }
2605                 mSettings.mPermissions.remove(name);
2606                 mSettings.writeLPr();
2607             }
2608         }
2609     }
2610 
checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp)2611     private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2612         int index = pkg.requestedPermissions.indexOf(bp.name);
2613         if (index == -1) {
2614             throw new SecurityException("Package " + pkg.packageName
2615                     + " has not requested permission " + bp.name);
2616         }
2617         boolean isNormal =
2618                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2619                         == PermissionInfo.PROTECTION_NORMAL);
2620         boolean isDangerous =
2621                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2622                         == PermissionInfo.PROTECTION_DANGEROUS);
2623         boolean isDevelopment =
2624                 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2625 
2626         if (!isNormal && !isDangerous && !isDevelopment) {
2627             throw new SecurityException("Permission " + bp.name
2628                     + " is not a changeable permission type");
2629         }
2630 
2631         if (isNormal || isDangerous) {
2632             if (pkg.requestedPermissionsRequired.get(index)) {
2633                 throw new SecurityException("Can't change " + bp.name
2634                         + ". It is required by the application");
2635             }
2636         }
2637     }
2638 
2639     @Override
grantPermission(String packageName, String permissionName)2640     public void grantPermission(String packageName, String permissionName) {
2641         mContext.enforceCallingOrSelfPermission(
2642                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2643         synchronized (mPackages) {
2644             final PackageParser.Package pkg = mPackages.get(packageName);
2645             if (pkg == null) {
2646                 throw new IllegalArgumentException("Unknown package: " + packageName);
2647             }
2648             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2649             if (bp == null) {
2650                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2651             }
2652 
2653             checkGrantRevokePermissions(pkg, bp);
2654 
2655             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2656             if (ps == null) {
2657                 return;
2658             }
2659             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2660             if (gp.grantedPermissions.add(permissionName)) {
2661                 if (ps.haveGids) {
2662                     gp.gids = appendInts(gp.gids, bp.gids);
2663                 }
2664                 mSettings.writeLPr();
2665             }
2666         }
2667     }
2668 
2669     @Override
revokePermission(String packageName, String permissionName)2670     public void revokePermission(String packageName, String permissionName) {
2671         int changedAppId = -1;
2672 
2673         synchronized (mPackages) {
2674             final PackageParser.Package pkg = mPackages.get(packageName);
2675             if (pkg == null) {
2676                 throw new IllegalArgumentException("Unknown package: " + packageName);
2677             }
2678             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2679                 mContext.enforceCallingOrSelfPermission(
2680                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2681             }
2682             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2683             if (bp == null) {
2684                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2685             }
2686 
2687             checkGrantRevokePermissions(pkg, bp);
2688 
2689             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2690             if (ps == null) {
2691                 return;
2692             }
2693             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2694             if (gp.grantedPermissions.remove(permissionName)) {
2695                 gp.grantedPermissions.remove(permissionName);
2696                 if (ps.haveGids) {
2697                     gp.gids = removeInts(gp.gids, bp.gids);
2698                 }
2699                 mSettings.writeLPr();
2700                 changedAppId = ps.appId;
2701             }
2702         }
2703 
2704         if (changedAppId >= 0) {
2705             // We changed the perm on someone, kill its processes.
2706             IActivityManager am = ActivityManagerNative.getDefault();
2707             if (am != null) {
2708                 final int callingUserId = UserHandle.getCallingUserId();
2709                 final long ident = Binder.clearCallingIdentity();
2710                 try {
2711                     //XXX we should only revoke for the calling user's app permissions,
2712                     // but for now we impact all users.
2713                     //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2714                     //        "revoke " + permissionName);
2715                     int[] users = sUserManager.getUserIds();
2716                     for (int user : users) {
2717                         am.killUid(UserHandle.getUid(user, changedAppId),
2718                                 "revoke " + permissionName);
2719                     }
2720                 } catch (RemoteException e) {
2721                 } finally {
2722                     Binder.restoreCallingIdentity(ident);
2723                 }
2724             }
2725         }
2726     }
2727 
2728     @Override
isProtectedBroadcast(String actionName)2729     public boolean isProtectedBroadcast(String actionName) {
2730         synchronized (mPackages) {
2731             return mProtectedBroadcasts.contains(actionName);
2732         }
2733     }
2734 
2735     @Override
checkSignatures(String pkg1, String pkg2)2736     public int checkSignatures(String pkg1, String pkg2) {
2737         synchronized (mPackages) {
2738             final PackageParser.Package p1 = mPackages.get(pkg1);
2739             final PackageParser.Package p2 = mPackages.get(pkg2);
2740             if (p1 == null || p1.mExtras == null
2741                     || p2 == null || p2.mExtras == null) {
2742                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2743             }
2744             return compareSignatures(p1.mSignatures, p2.mSignatures);
2745         }
2746     }
2747 
2748     @Override
checkUidSignatures(int uid1, int uid2)2749     public int checkUidSignatures(int uid1, int uid2) {
2750         // Map to base uids.
2751         uid1 = UserHandle.getAppId(uid1);
2752         uid2 = UserHandle.getAppId(uid2);
2753         // reader
2754         synchronized (mPackages) {
2755             Signature[] s1;
2756             Signature[] s2;
2757             Object obj = mSettings.getUserIdLPr(uid1);
2758             if (obj != null) {
2759                 if (obj instanceof SharedUserSetting) {
2760                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2761                 } else if (obj instanceof PackageSetting) {
2762                     s1 = ((PackageSetting)obj).signatures.mSignatures;
2763                 } else {
2764                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2765                 }
2766             } else {
2767                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2768             }
2769             obj = mSettings.getUserIdLPr(uid2);
2770             if (obj != null) {
2771                 if (obj instanceof SharedUserSetting) {
2772                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2773                 } else if (obj instanceof PackageSetting) {
2774                     s2 = ((PackageSetting)obj).signatures.mSignatures;
2775                 } else {
2776                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2777                 }
2778             } else {
2779                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2780             }
2781             return compareSignatures(s1, s2);
2782         }
2783     }
2784 
2785     /**
2786      * Compares two sets of signatures. Returns:
2787      * <br />
2788      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
2789      * <br />
2790      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
2791      * <br />
2792      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
2793      * <br />
2794      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
2795      * <br />
2796      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
2797      */
compareSignatures(Signature[] s1, Signature[] s2)2798     static int compareSignatures(Signature[] s1, Signature[] s2) {
2799         if (s1 == null) {
2800             return s2 == null
2801                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
2802                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2803         }
2804 
2805         if (s2 == null) {
2806             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2807         }
2808 
2809         if (s1.length != s2.length) {
2810             return PackageManager.SIGNATURE_NO_MATCH;
2811         }
2812 
2813         // Since both signature sets are of size 1, we can compare without HashSets.
2814         if (s1.length == 1) {
2815             return s1[0].equals(s2[0]) ?
2816                     PackageManager.SIGNATURE_MATCH :
2817                     PackageManager.SIGNATURE_NO_MATCH;
2818         }
2819 
2820         ArraySet<Signature> set1 = new ArraySet<Signature>();
2821         for (Signature sig : s1) {
2822             set1.add(sig);
2823         }
2824         ArraySet<Signature> set2 = new ArraySet<Signature>();
2825         for (Signature sig : s2) {
2826             set2.add(sig);
2827         }
2828         // Make sure s2 contains all signatures in s1.
2829         if (set1.equals(set2)) {
2830             return PackageManager.SIGNATURE_MATCH;
2831         }
2832         return PackageManager.SIGNATURE_NO_MATCH;
2833     }
2834 
2835     /**
2836      * If the database version for this type of package (internal storage or
2837      * external storage) is less than the version where package signatures
2838      * were updated, return true.
2839      */
isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg)2840     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
2841         return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
2842                 DatabaseVersion.SIGNATURE_END_ENTITY))
2843                 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
2844                         DatabaseVersion.SIGNATURE_END_ENTITY));
2845     }
2846 
2847     /**
2848      * Used for backward compatibility to make sure any packages with
2849      * certificate chains get upgraded to the new style. {@code existingSigs}
2850      * will be in the old format (since they were stored on disk from before the
2851      * system upgrade) and {@code scannedSigs} will be in the newer format.
2852      */
compareSignaturesCompat(PackageSignatures existingSigs, PackageParser.Package scannedPkg)2853     private int compareSignaturesCompat(PackageSignatures existingSigs,
2854             PackageParser.Package scannedPkg) {
2855         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
2856             return PackageManager.SIGNATURE_NO_MATCH;
2857         }
2858 
2859         ArraySet<Signature> existingSet = new ArraySet<Signature>();
2860         for (Signature sig : existingSigs.mSignatures) {
2861             existingSet.add(sig);
2862         }
2863         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
2864         for (Signature sig : scannedPkg.mSignatures) {
2865             try {
2866                 Signature[] chainSignatures = sig.getChainSignatures();
2867                 for (Signature chainSig : chainSignatures) {
2868                     scannedCompatSet.add(chainSig);
2869                 }
2870             } catch (CertificateEncodingException e) {
2871                 scannedCompatSet.add(sig);
2872             }
2873         }
2874         /*
2875          * Make sure the expanded scanned set contains all signatures in the
2876          * existing one.
2877          */
2878         if (scannedCompatSet.equals(existingSet)) {
2879             // Migrate the old signatures to the new scheme.
2880             existingSigs.assignSignatures(scannedPkg.mSignatures);
2881             // The new KeySets will be re-added later in the scanning process.
2882             synchronized (mPackages) {
2883                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
2884             }
2885             return PackageManager.SIGNATURE_MATCH;
2886         }
2887         return PackageManager.SIGNATURE_NO_MATCH;
2888     }
2889 
isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg)2890     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
2891         if (isExternal(scannedPkg)) {
2892             return mSettings.isExternalDatabaseVersionOlderThan(
2893                     DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
2894         } else {
2895             return mSettings.isInternalDatabaseVersionOlderThan(
2896                     DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
2897         }
2898     }
2899 
compareSignaturesRecover(PackageSignatures existingSigs, PackageParser.Package scannedPkg)2900     private int compareSignaturesRecover(PackageSignatures existingSigs,
2901             PackageParser.Package scannedPkg) {
2902         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
2903             return PackageManager.SIGNATURE_NO_MATCH;
2904         }
2905 
2906         String msg = null;
2907         try {
2908             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
2909                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
2910                         + scannedPkg.packageName);
2911                 return PackageManager.SIGNATURE_MATCH;
2912             }
2913         } catch (CertificateException e) {
2914             msg = e.getMessage();
2915         }
2916 
2917         logCriticalInfo(Log.INFO,
2918                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
2919         return PackageManager.SIGNATURE_NO_MATCH;
2920     }
2921 
2922     @Override
getPackagesForUid(int uid)2923     public String[] getPackagesForUid(int uid) {
2924         uid = UserHandle.getAppId(uid);
2925         // reader
2926         synchronized (mPackages) {
2927             Object obj = mSettings.getUserIdLPr(uid);
2928             if (obj instanceof SharedUserSetting) {
2929                 final SharedUserSetting sus = (SharedUserSetting) obj;
2930                 final int N = sus.packages.size();
2931                 final String[] res = new String[N];
2932                 final Iterator<PackageSetting> it = sus.packages.iterator();
2933                 int i = 0;
2934                 while (it.hasNext()) {
2935                     res[i++] = it.next().name;
2936                 }
2937                 return res;
2938             } else if (obj instanceof PackageSetting) {
2939                 final PackageSetting ps = (PackageSetting) obj;
2940                 return new String[] { ps.name };
2941             }
2942         }
2943         return null;
2944     }
2945 
2946     @Override
getNameForUid(int uid)2947     public String getNameForUid(int uid) {
2948         // reader
2949         synchronized (mPackages) {
2950             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2951             if (obj instanceof SharedUserSetting) {
2952                 final SharedUserSetting sus = (SharedUserSetting) obj;
2953                 return sus.name + ":" + sus.userId;
2954             } else if (obj instanceof PackageSetting) {
2955                 final PackageSetting ps = (PackageSetting) obj;
2956                 return ps.name;
2957             }
2958         }
2959         return null;
2960     }
2961 
2962     @Override
getUidForSharedUser(String sharedUserName)2963     public int getUidForSharedUser(String sharedUserName) {
2964         if(sharedUserName == null) {
2965             return -1;
2966         }
2967         // reader
2968         synchronized (mPackages) {
2969             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2970             if (suid == null) {
2971                 return -1;
2972             }
2973             return suid.userId;
2974         }
2975     }
2976 
2977     @Override
getFlagsForUid(int uid)2978     public int getFlagsForUid(int uid) {
2979         synchronized (mPackages) {
2980             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2981             if (obj instanceof SharedUserSetting) {
2982                 final SharedUserSetting sus = (SharedUserSetting) obj;
2983                 return sus.pkgFlags;
2984             } else if (obj instanceof PackageSetting) {
2985                 final PackageSetting ps = (PackageSetting) obj;
2986                 return ps.pkgFlags;
2987             }
2988         }
2989         return 0;
2990     }
2991 
2992     @Override
isUidPrivileged(int uid)2993     public boolean isUidPrivileged(int uid) {
2994         uid = UserHandle.getAppId(uid);
2995         // reader
2996         synchronized (mPackages) {
2997             Object obj = mSettings.getUserIdLPr(uid);
2998             if (obj instanceof SharedUserSetting) {
2999                 final SharedUserSetting sus = (SharedUserSetting) obj;
3000                 final Iterator<PackageSetting> it = sus.packages.iterator();
3001                 while (it.hasNext()) {
3002                     if (it.next().isPrivileged()) {
3003                         return true;
3004                     }
3005                 }
3006             } else if (obj instanceof PackageSetting) {
3007                 final PackageSetting ps = (PackageSetting) obj;
3008                 return ps.isPrivileged();
3009             }
3010         }
3011         return false;
3012     }
3013 
3014     @Override
getAppOpPermissionPackages(String permissionName)3015     public String[] getAppOpPermissionPackages(String permissionName) {
3016         synchronized (mPackages) {
3017             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
3018             if (pkgs == null) {
3019                 return null;
3020             }
3021             return pkgs.toArray(new String[pkgs.size()]);
3022         }
3023     }
3024 
3025     @Override
resolveIntent(Intent intent, String resolvedType, int flags, int userId)3026     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
3027             int flags, int userId) {
3028         if (!sUserManager.exists(userId)) return null;
3029         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
3030         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3031         return chooseBestActivity(intent, resolvedType, flags, query, userId);
3032     }
3033 
3034     @Override
setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)3035     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
3036             IntentFilter filter, int match, ComponentName activity) {
3037         final int userId = UserHandle.getCallingUserId();
3038         if (DEBUG_PREFERRED) {
3039             Log.v(TAG, "setLastChosenActivity intent=" + intent
3040                 + " resolvedType=" + resolvedType
3041                 + " flags=" + flags
3042                 + " filter=" + filter
3043                 + " match=" + match
3044                 + " activity=" + activity);
3045             filter.dump(new PrintStreamPrinter(System.out), "    ");
3046         }
3047         intent.setComponent(null);
3048         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3049         // Find any earlier preferred or last chosen entries and nuke them
3050         findPreferredActivity(intent, resolvedType,
3051                 flags, query, 0, false, true, false, userId);
3052         // Add the new activity as the last chosen for this filter
3053         addPreferredActivityInternal(filter, match, null, activity, false, userId,
3054                 "Setting last chosen");
3055     }
3056 
3057     @Override
getLastChosenActivity(Intent intent, String resolvedType, int flags)3058     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
3059         final int userId = UserHandle.getCallingUserId();
3060         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
3061         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3062         return findPreferredActivity(intent, resolvedType, flags, query, 0,
3063                 false, false, false, userId);
3064     }
3065 
chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int userId)3066     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
3067             int flags, List<ResolveInfo> query, int userId) {
3068         if (query != null) {
3069             final int N = query.size();
3070             if (N == 1) {
3071                 return query.get(0);
3072             } else if (N > 1) {
3073                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3074                 // If there is more than one activity with the same priority,
3075                 // then let the user decide between them.
3076                 ResolveInfo r0 = query.get(0);
3077                 ResolveInfo r1 = query.get(1);
3078                 if (DEBUG_INTENT_MATCHING || debug) {
3079                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
3080                             + r1.activityInfo.name + "=" + r1.priority);
3081                 }
3082                 // If the first activity has a higher priority, or a different
3083                 // default, then it is always desireable to pick it.
3084                 if (r0.priority != r1.priority
3085                         || r0.preferredOrder != r1.preferredOrder
3086                         || r0.isDefault != r1.isDefault) {
3087                     return query.get(0);
3088                 }
3089                 // If we have saved a preference for a preferred activity for
3090                 // this Intent, use that.
3091                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
3092                         flags, query, r0.priority, true, false, debug, userId);
3093                 if (ri != null) {
3094                     return ri;
3095                 }
3096                 if (userId != 0) {
3097                     ri = new ResolveInfo(mResolveInfo);
3098                     ri.activityInfo = new ActivityInfo(ri.activityInfo);
3099                     ri.activityInfo.applicationInfo = new ApplicationInfo(
3100                             ri.activityInfo.applicationInfo);
3101                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
3102                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
3103                     return ri;
3104                 }
3105                 return mResolveInfo;
3106             }
3107         }
3108         return null;
3109     }
3110 
findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)3111     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
3112             int flags, List<ResolveInfo> query, boolean debug, int userId) {
3113         final int N = query.size();
3114         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
3115                 .get(userId);
3116         // Get the list of persistent preferred activities that handle the intent
3117         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
3118         List<PersistentPreferredActivity> pprefs = ppir != null
3119                 ? ppir.queryIntent(intent, resolvedType,
3120                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3121                 : null;
3122         if (pprefs != null && pprefs.size() > 0) {
3123             final int M = pprefs.size();
3124             for (int i=0; i<M; i++) {
3125                 final PersistentPreferredActivity ppa = pprefs.get(i);
3126                 if (DEBUG_PREFERRED || debug) {
3127                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
3128                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
3129                             + "\n  component=" + ppa.mComponent);
3130                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3131                 }
3132                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
3133                         flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3134                 if (DEBUG_PREFERRED || debug) {
3135                     Slog.v(TAG, "Found persistent preferred activity:");
3136                     if (ai != null) {
3137                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3138                     } else {
3139                         Slog.v(TAG, "  null");
3140                     }
3141                 }
3142                 if (ai == null) {
3143                     // This previously registered persistent preferred activity
3144                     // component is no longer known. Ignore it and do NOT remove it.
3145                     continue;
3146                 }
3147                 for (int j=0; j<N; j++) {
3148                     final ResolveInfo ri = query.get(j);
3149                     if (!ri.activityInfo.applicationInfo.packageName
3150                             .equals(ai.applicationInfo.packageName)) {
3151                         continue;
3152                     }
3153                     if (!ri.activityInfo.name.equals(ai.name)) {
3154                         continue;
3155                     }
3156                     //  Found a persistent preference that can handle the intent.
3157                     if (DEBUG_PREFERRED || debug) {
3158                         Slog.v(TAG, "Returning persistent preferred activity: " +
3159                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3160                     }
3161                     return ri;
3162                 }
3163             }
3164         }
3165         return null;
3166     }
3167 
findPreferredActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)3168     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
3169             List<ResolveInfo> query, int priority, boolean always,
3170             boolean removeMatches, boolean debug, int userId) {
3171         if (!sUserManager.exists(userId)) return null;
3172         // writer
3173         synchronized (mPackages) {
3174             if (intent.getSelector() != null) {
3175                 intent = intent.getSelector();
3176             }
3177             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
3178 
3179             // Try to find a matching persistent preferred activity.
3180             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
3181                     debug, userId);
3182 
3183             // If a persistent preferred activity matched, use it.
3184             if (pri != null) {
3185                 return pri;
3186             }
3187 
3188             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
3189             // Get the list of preferred activities that handle the intent
3190             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
3191             List<PreferredActivity> prefs = pir != null
3192                     ? pir.queryIntent(intent, resolvedType,
3193                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3194                     : null;
3195             if (prefs != null && prefs.size() > 0) {
3196                 boolean changed = false;
3197                 try {
3198                     // First figure out how good the original match set is.
3199                     // We will only allow preferred activities that came
3200                     // from the same match quality.
3201                     int match = 0;
3202 
3203                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
3204 
3205                     final int N = query.size();
3206                     for (int j=0; j<N; j++) {
3207                         final ResolveInfo ri = query.get(j);
3208                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
3209                                 + ": 0x" + Integer.toHexString(match));
3210                         if (ri.match > match) {
3211                             match = ri.match;
3212                         }
3213                     }
3214 
3215                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
3216                             + Integer.toHexString(match));
3217 
3218                     match &= IntentFilter.MATCH_CATEGORY_MASK;
3219                     final int M = prefs.size();
3220                     for (int i=0; i<M; i++) {
3221                         final PreferredActivity pa = prefs.get(i);
3222                         if (DEBUG_PREFERRED || debug) {
3223                             Slog.v(TAG, "Checking PreferredActivity ds="
3224                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
3225                                     + "\n  component=" + pa.mPref.mComponent);
3226                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3227                         }
3228                         if (pa.mPref.mMatch != match) {
3229                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
3230                                     + Integer.toHexString(pa.mPref.mMatch));
3231                             continue;
3232                         }
3233                         // If it's not an "always" type preferred activity and that's what we're
3234                         // looking for, skip it.
3235                         if (always && !pa.mPref.mAlways) {
3236                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
3237                             continue;
3238                         }
3239                         final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
3240                                 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3241                         if (DEBUG_PREFERRED || debug) {
3242                             Slog.v(TAG, "Found preferred activity:");
3243                             if (ai != null) {
3244                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3245                             } else {
3246                                 Slog.v(TAG, "  null");
3247                             }
3248                         }
3249                         if (ai == null) {
3250                             // This previously registered preferred activity
3251                             // component is no longer known.  Most likely an update
3252                             // to the app was installed and in the new version this
3253                             // component no longer exists.  Clean it up by removing
3254                             // it from the preferred activities list, and skip it.
3255                             Slog.w(TAG, "Removing dangling preferred activity: "
3256                                     + pa.mPref.mComponent);
3257                             pir.removeFilter(pa);
3258                             changed = true;
3259                             continue;
3260                         }
3261                         for (int j=0; j<N; j++) {
3262                             final ResolveInfo ri = query.get(j);
3263                             if (!ri.activityInfo.applicationInfo.packageName
3264                                     .equals(ai.applicationInfo.packageName)) {
3265                                 continue;
3266                             }
3267                             if (!ri.activityInfo.name.equals(ai.name)) {
3268                                 continue;
3269                             }
3270 
3271                             if (removeMatches) {
3272                                 pir.removeFilter(pa);
3273                                 changed = true;
3274                                 if (DEBUG_PREFERRED) {
3275                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
3276                                 }
3277                                 break;
3278                             }
3279 
3280                             // Okay we found a previously set preferred or last chosen app.
3281                             // If the result set is different from when this
3282                             // was created, we need to clear it and re-ask the
3283                             // user their preference, if we're looking for an "always" type entry.
3284                             if (always && !pa.mPref.sameSet(query)) {
3285                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
3286                                         + intent + " type " + resolvedType);
3287                                 if (DEBUG_PREFERRED) {
3288                                     Slog.v(TAG, "Removing preferred activity since set changed "
3289                                             + pa.mPref.mComponent);
3290                                 }
3291                                 pir.removeFilter(pa);
3292                                 // Re-add the filter as a "last chosen" entry (!always)
3293                                 PreferredActivity lastChosen = new PreferredActivity(
3294                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
3295                                 pir.addFilter(lastChosen);
3296                                 changed = true;
3297                                 return null;
3298                             }
3299 
3300                             // Yay! Either the set matched or we're looking for the last chosen
3301                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
3302                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3303                             return ri;
3304                         }
3305                     }
3306                 } finally {
3307                     if (changed) {
3308                         if (DEBUG_PREFERRED) {
3309                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
3310                         }
3311                         scheduleWritePackageRestrictionsLocked(userId);
3312                     }
3313                 }
3314             }
3315         }
3316         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
3317         return null;
3318     }
3319 
3320     /*
3321      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
3322      */
3323     @Override
canForwardTo(Intent intent, String resolvedType, int sourceUserId, int targetUserId)3324     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
3325             int targetUserId) {
3326         mContext.enforceCallingOrSelfPermission(
3327                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
3328         List<CrossProfileIntentFilter> matches =
3329                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
3330         if (matches != null) {
3331             int size = matches.size();
3332             for (int i = 0; i < size; i++) {
3333                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
3334             }
3335         }
3336         return false;
3337     }
3338 
getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)3339     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
3340             String resolvedType, int userId) {
3341         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
3342         if (resolver != null) {
3343             return resolver.queryIntent(intent, resolvedType, false, userId);
3344         }
3345         return null;
3346     }
3347 
3348     @Override
queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)3349     public List<ResolveInfo> queryIntentActivities(Intent intent,
3350             String resolvedType, int flags, int userId) {
3351         if (!sUserManager.exists(userId)) return Collections.emptyList();
3352         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
3353         ComponentName comp = intent.getComponent();
3354         if (comp == null) {
3355             if (intent.getSelector() != null) {
3356                 intent = intent.getSelector();
3357                 comp = intent.getComponent();
3358             }
3359         }
3360 
3361         if (comp != null) {
3362             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3363             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
3364             if (ai != null) {
3365                 final ResolveInfo ri = new ResolveInfo();
3366                 ri.activityInfo = ai;
3367                 list.add(ri);
3368             }
3369             return list;
3370         }
3371 
3372         // reader
3373         synchronized (mPackages) {
3374             final String pkgName = intent.getPackage();
3375             if (pkgName == null) {
3376                 List<CrossProfileIntentFilter> matchingFilters =
3377                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
3378                 // Check for results that need to skip the current profile.
3379                 ResolveInfo resolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
3380                         resolvedType, flags, userId);
3381                 if (resolveInfo != null) {
3382                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
3383                     result.add(resolveInfo);
3384                     return result;
3385                 }
3386                 // Check for cross profile results.
3387                 resolveInfo = queryCrossProfileIntents(
3388                         matchingFilters, intent, resolvedType, flags, userId);
3389 
3390                 // Check for results in the current profile.
3391                 List<ResolveInfo> result = mActivities.queryIntent(
3392                         intent, resolvedType, flags, userId);
3393                 if (resolveInfo != null) {
3394                     result.add(resolveInfo);
3395                     Collections.sort(result, mResolvePrioritySorter);
3396                 }
3397                 return result;
3398             }
3399             final PackageParser.Package pkg = mPackages.get(pkgName);
3400             if (pkg != null) {
3401                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
3402                         pkg.activities, userId);
3403             }
3404             return new ArrayList<ResolveInfo>();
3405         }
3406     }
3407 
querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)3408     private ResolveInfo querySkipCurrentProfileIntents(
3409             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3410             int flags, int sourceUserId) {
3411         if (matchingFilters != null) {
3412             int size = matchingFilters.size();
3413             for (int i = 0; i < size; i ++) {
3414                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3415                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
3416                     // Checking if there are activities in the target user that can handle the
3417                     // intent.
3418                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3419                             flags, sourceUserId);
3420                     if (resolveInfo != null) {
3421                         return resolveInfo;
3422                     }
3423                 }
3424             }
3425         }
3426         return null;
3427     }
3428 
3429     // Return matching ResolveInfo if any for skip current profile intent filters.
queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)3430     private ResolveInfo queryCrossProfileIntents(
3431             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3432             int flags, int sourceUserId) {
3433         if (matchingFilters != null) {
3434             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
3435             // match the same intent. For performance reasons, it is better not to
3436             // run queryIntent twice for the same userId
3437             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
3438             int size = matchingFilters.size();
3439             for (int i = 0; i < size; i++) {
3440                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3441                 int targetUserId = filter.getTargetUserId();
3442                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
3443                         && !alreadyTriedUserIds.get(targetUserId)) {
3444                     // Checking if there are activities in the target user that can handle the
3445                     // intent.
3446                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3447                             flags, sourceUserId);
3448                     if (resolveInfo != null) return resolveInfo;
3449                     alreadyTriedUserIds.put(targetUserId, true);
3450                 }
3451             }
3452         }
3453         return null;
3454     }
3455 
checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, String resolvedType, int flags, int sourceUserId)3456     private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
3457             String resolvedType, int flags, int sourceUserId) {
3458         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
3459                 resolvedType, flags, filter.getTargetUserId());
3460         if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
3461             return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
3462         }
3463         return null;
3464     }
3465 
createForwardingResolveInfo(IntentFilter filter, int sourceUserId, int targetUserId)3466     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
3467             int sourceUserId, int targetUserId) {
3468         ResolveInfo forwardingResolveInfo = new ResolveInfo();
3469         String className;
3470         if (targetUserId == UserHandle.USER_OWNER) {
3471             className = FORWARD_INTENT_TO_USER_OWNER;
3472         } else {
3473             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3474         }
3475         ComponentName forwardingActivityComponentName = new ComponentName(
3476                 mAndroidApplication.packageName, className);
3477         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
3478                 sourceUserId);
3479         if (targetUserId == UserHandle.USER_OWNER) {
3480             forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
3481             forwardingResolveInfo.noResourceId = true;
3482         }
3483         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3484         forwardingResolveInfo.priority = 0;
3485         forwardingResolveInfo.preferredOrder = 0;
3486         forwardingResolveInfo.match = 0;
3487         forwardingResolveInfo.isDefault = true;
3488         forwardingResolveInfo.filter = filter;
3489         forwardingResolveInfo.targetUserId = targetUserId;
3490         return forwardingResolveInfo;
3491     }
3492 
3493     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)3494     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
3495             Intent[] specifics, String[] specificTypes, Intent intent,
3496             String resolvedType, int flags, int userId) {
3497         if (!sUserManager.exists(userId)) return Collections.emptyList();
3498         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
3499                 false, "query intent activity options");
3500         final String resultsAction = intent.getAction();
3501 
3502         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
3503                 | PackageManager.GET_RESOLVED_FILTER, userId);
3504 
3505         if (DEBUG_INTENT_MATCHING) {
3506             Log.v(TAG, "Query " + intent + ": " + results);
3507         }
3508 
3509         int specificsPos = 0;
3510         int N;
3511 
3512         // todo: note that the algorithm used here is O(N^2).  This
3513         // isn't a problem in our current environment, but if we start running
3514         // into situations where we have more than 5 or 10 matches then this
3515         // should probably be changed to something smarter...
3516 
3517         // First we go through and resolve each of the specific items
3518         // that were supplied, taking care of removing any corresponding
3519         // duplicate items in the generic resolve list.
3520         if (specifics != null) {
3521             for (int i=0; i<specifics.length; i++) {
3522                 final Intent sintent = specifics[i];
3523                 if (sintent == null) {
3524                     continue;
3525                 }
3526 
3527                 if (DEBUG_INTENT_MATCHING) {
3528                     Log.v(TAG, "Specific #" + i + ": " + sintent);
3529                 }
3530 
3531                 String action = sintent.getAction();
3532                 if (resultsAction != null && resultsAction.equals(action)) {
3533                     // If this action was explicitly requested, then don't
3534                     // remove things that have it.
3535                     action = null;
3536                 }
3537 
3538                 ResolveInfo ri = null;
3539                 ActivityInfo ai = null;
3540 
3541                 ComponentName comp = sintent.getComponent();
3542                 if (comp == null) {
3543                     ri = resolveIntent(
3544                         sintent,
3545                         specificTypes != null ? specificTypes[i] : null,
3546                             flags, userId);
3547                     if (ri == null) {
3548                         continue;
3549                     }
3550                     if (ri == mResolveInfo) {
3551                         // ACK!  Must do something better with this.
3552                     }
3553                     ai = ri.activityInfo;
3554                     comp = new ComponentName(ai.applicationInfo.packageName,
3555                             ai.name);
3556                 } else {
3557                     ai = getActivityInfo(comp, flags, userId);
3558                     if (ai == null) {
3559                         continue;
3560                     }
3561                 }
3562 
3563                 // Look for any generic query activities that are duplicates
3564                 // of this specific one, and remove them from the results.
3565                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
3566                 N = results.size();
3567                 int j;
3568                 for (j=specificsPos; j<N; j++) {
3569                     ResolveInfo sri = results.get(j);
3570                     if ((sri.activityInfo.name.equals(comp.getClassName())
3571                             && sri.activityInfo.applicationInfo.packageName.equals(
3572                                     comp.getPackageName()))
3573                         || (action != null && sri.filter.matchAction(action))) {
3574                         results.remove(j);
3575                         if (DEBUG_INTENT_MATCHING) Log.v(
3576                             TAG, "Removing duplicate item from " + j
3577                             + " due to specific " + specificsPos);
3578                         if (ri == null) {
3579                             ri = sri;
3580                         }
3581                         j--;
3582                         N--;
3583                     }
3584                 }
3585 
3586                 // Add this specific item to its proper place.
3587                 if (ri == null) {
3588                     ri = new ResolveInfo();
3589                     ri.activityInfo = ai;
3590                 }
3591                 results.add(specificsPos, ri);
3592                 ri.specificIndex = i;
3593                 specificsPos++;
3594             }
3595         }
3596 
3597         // Now we go through the remaining generic results and remove any
3598         // duplicate actions that are found here.
3599         N = results.size();
3600         for (int i=specificsPos; i<N-1; i++) {
3601             final ResolveInfo rii = results.get(i);
3602             if (rii.filter == null) {
3603                 continue;
3604             }
3605 
3606             // Iterate over all of the actions of this result's intent
3607             // filter...  typically this should be just one.
3608             final Iterator<String> it = rii.filter.actionsIterator();
3609             if (it == null) {
3610                 continue;
3611             }
3612             while (it.hasNext()) {
3613                 final String action = it.next();
3614                 if (resultsAction != null && resultsAction.equals(action)) {
3615                     // If this action was explicitly requested, then don't
3616                     // remove things that have it.
3617                     continue;
3618                 }
3619                 for (int j=i+1; j<N; j++) {
3620                     final ResolveInfo rij = results.get(j);
3621                     if (rij.filter != null && rij.filter.hasAction(action)) {
3622                         results.remove(j);
3623                         if (DEBUG_INTENT_MATCHING) Log.v(
3624                             TAG, "Removing duplicate item from " + j
3625                             + " due to action " + action + " at " + i);
3626                         j--;
3627                         N--;
3628                     }
3629                 }
3630             }
3631 
3632             // If the caller didn't request filter information, drop it now
3633             // so we don't have to marshall/unmarshall it.
3634             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3635                 rii.filter = null;
3636             }
3637         }
3638 
3639         // Filter out the caller activity if so requested.
3640         if (caller != null) {
3641             N = results.size();
3642             for (int i=0; i<N; i++) {
3643                 ActivityInfo ainfo = results.get(i).activityInfo;
3644                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
3645                         && caller.getClassName().equals(ainfo.name)) {
3646                     results.remove(i);
3647                     break;
3648                 }
3649             }
3650         }
3651 
3652         // If the caller didn't request filter information,
3653         // drop them now so we don't have to
3654         // marshall/unmarshall it.
3655         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3656             N = results.size();
3657             for (int i=0; i<N; i++) {
3658                 results.get(i).filter = null;
3659             }
3660         }
3661 
3662         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
3663         return results;
3664     }
3665 
3666     @Override
queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)3667     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
3668             int userId) {
3669         if (!sUserManager.exists(userId)) return Collections.emptyList();
3670         ComponentName comp = intent.getComponent();
3671         if (comp == null) {
3672             if (intent.getSelector() != null) {
3673                 intent = intent.getSelector();
3674                 comp = intent.getComponent();
3675             }
3676         }
3677         if (comp != null) {
3678             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3679             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
3680             if (ai != null) {
3681                 ResolveInfo ri = new ResolveInfo();
3682                 ri.activityInfo = ai;
3683                 list.add(ri);
3684             }
3685             return list;
3686         }
3687 
3688         // reader
3689         synchronized (mPackages) {
3690             String pkgName = intent.getPackage();
3691             if (pkgName == null) {
3692                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
3693             }
3694             final PackageParser.Package pkg = mPackages.get(pkgName);
3695             if (pkg != null) {
3696                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
3697                         userId);
3698             }
3699             return null;
3700         }
3701     }
3702 
3703     @Override
resolveService(Intent intent, String resolvedType, int flags, int userId)3704     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
3705         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
3706         if (!sUserManager.exists(userId)) return null;
3707         if (query != null) {
3708             if (query.size() >= 1) {
3709                 // If there is more than one service with the same priority,
3710                 // just arbitrarily pick the first one.
3711                 return query.get(0);
3712             }
3713         }
3714         return null;
3715     }
3716 
3717     @Override
queryIntentServices(Intent intent, String resolvedType, int flags, int userId)3718     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
3719             int userId) {
3720         if (!sUserManager.exists(userId)) return Collections.emptyList();
3721         ComponentName comp = intent.getComponent();
3722         if (comp == null) {
3723             if (intent.getSelector() != null) {
3724                 intent = intent.getSelector();
3725                 comp = intent.getComponent();
3726             }
3727         }
3728         if (comp != null) {
3729             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3730             final ServiceInfo si = getServiceInfo(comp, flags, userId);
3731             if (si != null) {
3732                 final ResolveInfo ri = new ResolveInfo();
3733                 ri.serviceInfo = si;
3734                 list.add(ri);
3735             }
3736             return list;
3737         }
3738 
3739         // reader
3740         synchronized (mPackages) {
3741             String pkgName = intent.getPackage();
3742             if (pkgName == null) {
3743                 return mServices.queryIntent(intent, resolvedType, flags, userId);
3744             }
3745             final PackageParser.Package pkg = mPackages.get(pkgName);
3746             if (pkg != null) {
3747                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3748                         userId);
3749             }
3750             return null;
3751         }
3752     }
3753 
3754     @Override
queryIntentContentProviders( Intent intent, String resolvedType, int flags, int userId)3755     public List<ResolveInfo> queryIntentContentProviders(
3756             Intent intent, String resolvedType, int flags, int userId) {
3757         if (!sUserManager.exists(userId)) return Collections.emptyList();
3758         ComponentName comp = intent.getComponent();
3759         if (comp == null) {
3760             if (intent.getSelector() != null) {
3761                 intent = intent.getSelector();
3762                 comp = intent.getComponent();
3763             }
3764         }
3765         if (comp != null) {
3766             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3767             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
3768             if (pi != null) {
3769                 final ResolveInfo ri = new ResolveInfo();
3770                 ri.providerInfo = pi;
3771                 list.add(ri);
3772             }
3773             return list;
3774         }
3775 
3776         // reader
3777         synchronized (mPackages) {
3778             String pkgName = intent.getPackage();
3779             if (pkgName == null) {
3780                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
3781             }
3782             final PackageParser.Package pkg = mPackages.get(pkgName);
3783             if (pkg != null) {
3784                 return mProviders.queryIntentForPackage(
3785                         intent, resolvedType, flags, pkg.providers, userId);
3786             }
3787             return null;
3788         }
3789     }
3790 
3791     @Override
getInstalledPackages(int flags, int userId)3792     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3793         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3794 
3795         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
3796 
3797         // writer
3798         synchronized (mPackages) {
3799             ArrayList<PackageInfo> list;
3800             if (listUninstalled) {
3801                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3802                 for (PackageSetting ps : mSettings.mPackages.values()) {
3803                     PackageInfo pi;
3804                     if (ps.pkg != null) {
3805                         pi = generatePackageInfo(ps.pkg, flags, userId);
3806                     } else {
3807                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3808                     }
3809                     if (pi != null) {
3810                         list.add(pi);
3811                     }
3812                 }
3813             } else {
3814                 list = new ArrayList<PackageInfo>(mPackages.size());
3815                 for (PackageParser.Package p : mPackages.values()) {
3816                     PackageInfo pi = generatePackageInfo(p, flags, userId);
3817                     if (pi != null) {
3818                         list.add(pi);
3819                     }
3820                 }
3821             }
3822 
3823             return new ParceledListSlice<PackageInfo>(list);
3824         }
3825     }
3826 
addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)3827     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3828             String[] permissions, boolean[] tmp, int flags, int userId) {
3829         int numMatch = 0;
3830         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3831         for (int i=0; i<permissions.length; i++) {
3832             if (gp.grantedPermissions.contains(permissions[i])) {
3833                 tmp[i] = true;
3834                 numMatch++;
3835             } else {
3836                 tmp[i] = false;
3837             }
3838         }
3839         if (numMatch == 0) {
3840             return;
3841         }
3842         PackageInfo pi;
3843         if (ps.pkg != null) {
3844             pi = generatePackageInfo(ps.pkg, flags, userId);
3845         } else {
3846             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3847         }
3848         // The above might return null in cases of uninstalled apps or install-state
3849         // skew across users/profiles.
3850         if (pi != null) {
3851             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3852                 if (numMatch == permissions.length) {
3853                     pi.requestedPermissions = permissions;
3854                 } else {
3855                     pi.requestedPermissions = new String[numMatch];
3856                     numMatch = 0;
3857                     for (int i=0; i<permissions.length; i++) {
3858                         if (tmp[i]) {
3859                             pi.requestedPermissions[numMatch] = permissions[i];
3860                             numMatch++;
3861                         }
3862                     }
3863                 }
3864             }
3865             list.add(pi);
3866         }
3867     }
3868 
3869     @Override
getPackagesHoldingPermissions( String[] permissions, int flags, int userId)3870     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3871             String[] permissions, int flags, int userId) {
3872         if (!sUserManager.exists(userId)) return null;
3873         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3874 
3875         // writer
3876         synchronized (mPackages) {
3877             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3878             boolean[] tmpBools = new boolean[permissions.length];
3879             if (listUninstalled) {
3880                 for (PackageSetting ps : mSettings.mPackages.values()) {
3881                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3882                 }
3883             } else {
3884                 for (PackageParser.Package pkg : mPackages.values()) {
3885                     PackageSetting ps = (PackageSetting)pkg.mExtras;
3886                     if (ps != null) {
3887                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3888                                 userId);
3889                     }
3890                 }
3891             }
3892 
3893             return new ParceledListSlice<PackageInfo>(list);
3894         }
3895     }
3896 
3897     @Override
getInstalledApplications(int flags, int userId)3898     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3899         if (!sUserManager.exists(userId)) return null;
3900         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3901 
3902         // writer
3903         synchronized (mPackages) {
3904             ArrayList<ApplicationInfo> list;
3905             if (listUninstalled) {
3906                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3907                 for (PackageSetting ps : mSettings.mPackages.values()) {
3908                     ApplicationInfo ai;
3909                     if (ps.pkg != null) {
3910                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3911                                 ps.readUserState(userId), userId);
3912                     } else {
3913                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3914                     }
3915                     if (ai != null) {
3916                         list.add(ai);
3917                     }
3918                 }
3919             } else {
3920                 list = new ArrayList<ApplicationInfo>(mPackages.size());
3921                 for (PackageParser.Package p : mPackages.values()) {
3922                     if (p.mExtras != null) {
3923                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3924                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3925                         if (ai != null) {
3926                             list.add(ai);
3927                         }
3928                     }
3929                 }
3930             }
3931 
3932             return new ParceledListSlice<ApplicationInfo>(list);
3933         }
3934     }
3935 
getPersistentApplications(int flags)3936     public List<ApplicationInfo> getPersistentApplications(int flags) {
3937         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3938 
3939         // reader
3940         synchronized (mPackages) {
3941             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3942             final int userId = UserHandle.getCallingUserId();
3943             while (i.hasNext()) {
3944                 final PackageParser.Package p = i.next();
3945                 if (p.applicationInfo != null
3946                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3947                         && (!mSafeMode || isSystemApp(p))) {
3948                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
3949                     if (ps != null) {
3950                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3951                                 ps.readUserState(userId), userId);
3952                         if (ai != null) {
3953                             finalList.add(ai);
3954                         }
3955                     }
3956                 }
3957             }
3958         }
3959 
3960         return finalList;
3961     }
3962 
3963     @Override
resolveContentProvider(String name, int flags, int userId)3964     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3965         if (!sUserManager.exists(userId)) return null;
3966         // reader
3967         synchronized (mPackages) {
3968             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
3969             PackageSetting ps = provider != null
3970                     ? mSettings.mPackages.get(provider.owner.packageName)
3971                     : null;
3972             return ps != null
3973                     && mSettings.isEnabledLPr(provider.info, flags, userId)
3974                     && (!mSafeMode || (provider.info.applicationInfo.flags
3975                             &ApplicationInfo.FLAG_SYSTEM) != 0)
3976                     ? PackageParser.generateProviderInfo(provider, flags,
3977                             ps.readUserState(userId), userId)
3978                     : null;
3979         }
3980     }
3981 
3982     /**
3983      * @deprecated
3984      */
3985     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)3986     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3987         // reader
3988         synchronized (mPackages) {
3989             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
3990                     .entrySet().iterator();
3991             final int userId = UserHandle.getCallingUserId();
3992             while (i.hasNext()) {
3993                 Map.Entry<String, PackageParser.Provider> entry = i.next();
3994                 PackageParser.Provider p = entry.getValue();
3995                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3996 
3997                 if (ps != null && p.syncable
3998                         && (!mSafeMode || (p.info.applicationInfo.flags
3999                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
4000                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
4001                             ps.readUserState(userId), userId);
4002                     if (info != null) {
4003                         outNames.add(entry.getKey());
4004                         outInfo.add(info);
4005                     }
4006                 }
4007             }
4008         }
4009     }
4010 
4011     @Override
queryContentProviders(String processName, int uid, int flags)4012     public List<ProviderInfo> queryContentProviders(String processName,
4013             int uid, int flags) {
4014         ArrayList<ProviderInfo> finalList = null;
4015         // reader
4016         synchronized (mPackages) {
4017             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
4018             final int userId = processName != null ?
4019                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
4020             while (i.hasNext()) {
4021                 final PackageParser.Provider p = i.next();
4022                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
4023                 if (ps != null && p.info.authority != null
4024                         && (processName == null
4025                                 || (p.info.processName.equals(processName)
4026                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
4027                         && mSettings.isEnabledLPr(p.info, flags, userId)
4028                         && (!mSafeMode
4029                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
4030                     if (finalList == null) {
4031                         finalList = new ArrayList<ProviderInfo>(3);
4032                     }
4033                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
4034                             ps.readUserState(userId), userId);
4035                     if (info != null) {
4036                         finalList.add(info);
4037                     }
4038                 }
4039             }
4040         }
4041 
4042         if (finalList != null) {
4043             Collections.sort(finalList, mProviderInitOrderSorter);
4044         }
4045 
4046         return finalList;
4047     }
4048 
4049     @Override
getInstrumentationInfo(ComponentName name, int flags)4050     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
4051             int flags) {
4052         // reader
4053         synchronized (mPackages) {
4054             final PackageParser.Instrumentation i = mInstrumentation.get(name);
4055             return PackageParser.generateInstrumentationInfo(i, flags);
4056         }
4057     }
4058 
4059     @Override
queryInstrumentation(String targetPackage, int flags)4060     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
4061             int flags) {
4062         ArrayList<InstrumentationInfo> finalList =
4063             new ArrayList<InstrumentationInfo>();
4064 
4065         // reader
4066         synchronized (mPackages) {
4067             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
4068             while (i.hasNext()) {
4069                 final PackageParser.Instrumentation p = i.next();
4070                 if (targetPackage == null
4071                         || targetPackage.equals(p.info.targetPackage)) {
4072                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
4073                             flags);
4074                     if (ii != null) {
4075                         finalList.add(ii);
4076                     }
4077                 }
4078             }
4079         }
4080 
4081         return finalList;
4082     }
4083 
createIdmapsForPackageLI(PackageParser.Package pkg)4084     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
4085         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
4086         if (overlays == null) {
4087             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
4088             return;
4089         }
4090         for (PackageParser.Package opkg : overlays.values()) {
4091             // Not much to do if idmap fails: we already logged the error
4092             // and we certainly don't want to abort installation of pkg simply
4093             // because an overlay didn't fit properly. For these reasons,
4094             // ignore the return value of createIdmapForPackagePairLI.
4095             createIdmapForPackagePairLI(pkg, opkg);
4096         }
4097     }
4098 
createIdmapForPackagePairLI(PackageParser.Package pkg, PackageParser.Package opkg)4099     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
4100             PackageParser.Package opkg) {
4101         if (!opkg.mTrustedOverlay) {
4102             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
4103                     opkg.baseCodePath + ": overlay not trusted");
4104             return false;
4105         }
4106         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
4107         if (overlaySet == null) {
4108             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
4109                     opkg.baseCodePath + " but target package has no known overlays");
4110             return false;
4111         }
4112         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4113         // TODO: generate idmap for split APKs
4114         if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
4115             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
4116                     + opkg.baseCodePath);
4117             return false;
4118         }
4119         PackageParser.Package[] overlayArray =
4120             overlaySet.values().toArray(new PackageParser.Package[0]);
4121         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
4122             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
4123                 return p1.mOverlayPriority - p2.mOverlayPriority;
4124             }
4125         };
4126         Arrays.sort(overlayArray, cmp);
4127 
4128         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
4129         int i = 0;
4130         for (PackageParser.Package p : overlayArray) {
4131             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
4132         }
4133         return true;
4134     }
4135 
scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime)4136     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
4137         final File[] files = dir.listFiles();
4138         if (ArrayUtils.isEmpty(files)) {
4139             Log.d(TAG, "No files in app dir " + dir);
4140             return;
4141         }
4142 
4143         if (DEBUG_PACKAGE_SCANNING) {
4144             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
4145                     + " flags=0x" + Integer.toHexString(parseFlags));
4146         }
4147 
4148         for (File file : files) {
4149             final boolean isPackage = (isApkFile(file) || file.isDirectory())
4150                     && !PackageInstallerService.isStageName(file.getName());
4151             if (!isPackage) {
4152                 // Ignore entries which are not packages
4153                 continue;
4154             }
4155             try {
4156                 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
4157                         scanFlags, currentTime, null);
4158             } catch (PackageManagerException e) {
4159                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
4160 
4161                 // Delete invalid userdata apps
4162                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
4163                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
4164                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
4165                     if (file.isDirectory()) {
4166                         FileUtils.deleteContents(file);
4167                     }
4168                     file.delete();
4169                 }
4170             }
4171         }
4172     }
4173 
getSettingsProblemFile()4174     private static File getSettingsProblemFile() {
4175         File dataDir = Environment.getDataDirectory();
4176         File systemDir = new File(dataDir, "system");
4177         File fname = new File(systemDir, "uiderrors.txt");
4178         return fname;
4179     }
4180 
reportSettingsProblem(int priority, String msg)4181     static void reportSettingsProblem(int priority, String msg) {
4182         logCriticalInfo(priority, msg);
4183     }
4184 
logCriticalInfo(int priority, String msg)4185     static void logCriticalInfo(int priority, String msg) {
4186         Slog.println(priority, TAG, msg);
4187         EventLogTags.writePmCriticalInfo(msg);
4188         try {
4189             File fname = getSettingsProblemFile();
4190             FileOutputStream out = new FileOutputStream(fname, true);
4191             PrintWriter pw = new FastPrintWriter(out);
4192             SimpleDateFormat formatter = new SimpleDateFormat();
4193             String dateString = formatter.format(new Date(System.currentTimeMillis()));
4194             pw.println(dateString + ": " + msg);
4195             pw.close();
4196             FileUtils.setPermissions(
4197                     fname.toString(),
4198                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
4199                     -1, -1);
4200         } catch (java.io.IOException e) {
4201         }
4202     }
4203 
collectCertificatesLI(PackageParser pp, PackageSetting ps, PackageParser.Package pkg, File srcFile, int parseFlags)4204     private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
4205             PackageParser.Package pkg, File srcFile, int parseFlags)
4206             throws PackageManagerException {
4207         if (ps != null
4208                 && ps.codePath.equals(srcFile)
4209                 && ps.timeStamp == srcFile.lastModified()
4210                 && !isCompatSignatureUpdateNeeded(pkg)
4211                 && !isRecoverSignatureUpdateNeeded(pkg)) {
4212             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
4213             if (ps.signatures.mSignatures != null
4214                     && ps.signatures.mSignatures.length != 0
4215                     && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
4216                 // Optimization: reuse the existing cached certificates
4217                 // if the package appears to be unchanged.
4218                 pkg.mSignatures = ps.signatures.mSignatures;
4219                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
4220                 synchronized (mPackages) {
4221                     pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
4222                 }
4223                 return;
4224             }
4225 
4226             Slog.w(TAG, "PackageSetting for " + ps.name
4227                     + " is missing signatures.  Collecting certs again to recover them.");
4228         } else {
4229             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
4230         }
4231 
4232         try {
4233             pp.collectCertificates(pkg, parseFlags);
4234             pp.collectManifestDigest(pkg);
4235         } catch (PackageParserException e) {
4236             throw PackageManagerException.from(e);
4237         }
4238     }
4239 
4240     /*
4241      *  Scan a package and return the newly parsed package.
4242      *  Returns null in case of errors and the error code is stored in mLastScanError
4243      */
scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)4244     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
4245             long currentTime, UserHandle user) throws PackageManagerException {
4246         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
4247         parseFlags |= mDefParseFlags;
4248         PackageParser pp = new PackageParser();
4249         pp.setSeparateProcesses(mSeparateProcesses);
4250         pp.setOnlyCoreApps(mOnlyCore);
4251         pp.setDisplayMetrics(mMetrics);
4252 
4253         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
4254             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
4255         }
4256 
4257         final PackageParser.Package pkg;
4258         try {
4259             pkg = pp.parsePackage(scanFile, parseFlags);
4260         } catch (PackageParserException e) {
4261             throw PackageManagerException.from(e);
4262         }
4263 
4264         PackageSetting ps = null;
4265         PackageSetting updatedPkg;
4266         // reader
4267         synchronized (mPackages) {
4268             // Look to see if we already know about this package.
4269             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
4270             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
4271                 // This package has been renamed to its original name.  Let's
4272                 // use that.
4273                 ps = mSettings.peekPackageLPr(oldName);
4274             }
4275             // If there was no original package, see one for the real package name.
4276             if (ps == null) {
4277                 ps = mSettings.peekPackageLPr(pkg.packageName);
4278             }
4279             // Check to see if this package could be hiding/updating a system
4280             // package.  Must look for it either under the original or real
4281             // package name depending on our state.
4282             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
4283             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
4284         }
4285         boolean updatedPkgBetter = false;
4286         // First check if this is a system package that may involve an update
4287         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4288             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
4289             // it needs to drop FLAG_PRIVILEGED.
4290             if (locationIsPrivileged(scanFile)) {
4291                 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
4292             } else {
4293                 updatedPkg.pkgFlags &= ~ApplicationInfo.FLAG_PRIVILEGED;
4294             }
4295 
4296             if (ps != null && !ps.codePath.equals(scanFile)) {
4297                 // The path has changed from what was last scanned...  check the
4298                 // version of the new path against what we have stored to determine
4299                 // what to do.
4300                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
4301                 if (pkg.mVersionCode <= ps.versionCode) {
4302                     // The system package has been updated and the code path does not match
4303                     // Ignore entry. Skip it.
4304                     Slog.i(TAG, "Package " + ps.name + " at " + scanFile
4305                             + " ignored: updated version " + ps.versionCode
4306                             + " better than this " + pkg.mVersionCode);
4307                     if (!updatedPkg.codePath.equals(scanFile)) {
4308                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
4309                                 + ps.name + " changing from " + updatedPkg.codePathString
4310                                 + " to " + scanFile);
4311                         updatedPkg.codePath = scanFile;
4312                         updatedPkg.codePathString = scanFile.toString();
4313                     }
4314                     updatedPkg.pkg = pkg;
4315                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
4316                 } else {
4317                     // The current app on the system partition is better than
4318                     // what we have updated to on the data partition; switch
4319                     // back to the system partition version.
4320                     // At this point, its safely assumed that package installation for
4321                     // apps in system partition will go through. If not there won't be a working
4322                     // version of the app
4323                     // writer
4324                     synchronized (mPackages) {
4325                         // Just remove the loaded entries from package lists.
4326                         mPackages.remove(ps.name);
4327                     }
4328 
4329                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4330                             + " reverting from " + ps.codePathString
4331                             + ": new version " + pkg.mVersionCode
4332                             + " better than installed " + ps.versionCode);
4333 
4334                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4335                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4336                             getAppDexInstructionSets(ps));
4337                     synchronized (mInstallLock) {
4338                         args.cleanUpResourcesLI();
4339                     }
4340                     synchronized (mPackages) {
4341                         mSettings.enableSystemPackageLPw(ps.name);
4342                     }
4343                     updatedPkgBetter = true;
4344                 }
4345             }
4346         }
4347 
4348         if (updatedPkg != null) {
4349             // An updated system app will not have the PARSE_IS_SYSTEM flag set
4350             // initially
4351             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
4352 
4353             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
4354             // flag set initially
4355             if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
4356                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
4357             }
4358         }
4359 
4360         // Verify certificates against what was last scanned
4361         collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
4362 
4363         /*
4364          * A new system app appeared, but we already had a non-system one of the
4365          * same name installed earlier.
4366          */
4367         boolean shouldHideSystemApp = false;
4368         if (updatedPkg == null && ps != null
4369                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
4370             /*
4371              * Check to make sure the signatures match first. If they don't,
4372              * wipe the installed application and its data.
4373              */
4374             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
4375                     != PackageManager.SIGNATURE_MATCH) {
4376                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
4377                         + " signatures don't match existing userdata copy; removing");
4378                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
4379                 ps = null;
4380             } else {
4381                 /*
4382                  * If the newly-added system app is an older version than the
4383                  * already installed version, hide it. It will be scanned later
4384                  * and re-added like an update.
4385                  */
4386                 if (pkg.mVersionCode <= ps.versionCode) {
4387                     shouldHideSystemApp = true;
4388                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
4389                             + " but new version " + pkg.mVersionCode + " better than installed "
4390                             + ps.versionCode + "; hiding system");
4391                 } else {
4392                     /*
4393                      * The newly found system app is a newer version that the
4394                      * one previously installed. Simply remove the
4395                      * already-installed application and replace it with our own
4396                      * while keeping the application data.
4397                      */
4398                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4399                             + " reverting from " + ps.codePathString + ": new version "
4400                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
4401                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4402                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4403                             getAppDexInstructionSets(ps));
4404                     synchronized (mInstallLock) {
4405                         args.cleanUpResourcesLI();
4406                     }
4407                 }
4408             }
4409         }
4410 
4411         // The apk is forward locked (not public) if its code and resources
4412         // are kept in different files. (except for app in either system or
4413         // vendor path).
4414         // TODO grab this value from PackageSettings
4415         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4416             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
4417                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
4418             }
4419         }
4420 
4421         // TODO: extend to support forward-locked splits
4422         String resourcePath = null;
4423         String baseResourcePath = null;
4424         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
4425             if (ps != null && ps.resourcePathString != null) {
4426                 resourcePath = ps.resourcePathString;
4427                 baseResourcePath = ps.resourcePathString;
4428             } else {
4429                 // Should not happen at all. Just log an error.
4430                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
4431             }
4432         } else {
4433             resourcePath = pkg.codePath;
4434             baseResourcePath = pkg.baseCodePath;
4435         }
4436 
4437         // Set application objects path explicitly.
4438         pkg.applicationInfo.setCodePath(pkg.codePath);
4439         pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
4440         pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
4441         pkg.applicationInfo.setResourcePath(resourcePath);
4442         pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
4443         pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
4444 
4445         // Note that we invoke the following method only if we are about to unpack an application
4446         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
4447                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
4448 
4449         /*
4450          * If the system app should be overridden by a previously installed
4451          * data, hide the system app now and let the /data/app scan pick it up
4452          * again.
4453          */
4454         if (shouldHideSystemApp) {
4455             synchronized (mPackages) {
4456                 /*
4457                  * We have to grant systems permissions before we hide, because
4458                  * grantPermissions will assume the package update is trying to
4459                  * expand its permissions.
4460                  */
4461                 grantPermissionsLPw(pkg, true, pkg.packageName);
4462                 mSettings.disableSystemPackageLPw(pkg.packageName);
4463             }
4464         }
4465 
4466         return scannedPkg;
4467     }
4468 
fixProcessName(String defProcessName, String processName, int uid)4469     private static String fixProcessName(String defProcessName,
4470             String processName, int uid) {
4471         if (processName == null) {
4472             return defProcessName;
4473         }
4474         return processName;
4475     }
4476 
verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)4477     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
4478             throws PackageManagerException {
4479         if (pkgSetting.signatures.mSignatures != null) {
4480             // Already existing package. Make sure signatures match
4481             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
4482                     == PackageManager.SIGNATURE_MATCH;
4483             if (!match) {
4484                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
4485                         == PackageManager.SIGNATURE_MATCH;
4486             }
4487             if (!match) {
4488                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
4489                         == PackageManager.SIGNATURE_MATCH;
4490             }
4491             if (!match) {
4492                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
4493                         + pkg.packageName + " signatures do not match the "
4494                         + "previously installed version; ignoring!");
4495             }
4496         }
4497 
4498         // Check for shared user signatures
4499         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
4500             // Already existing package. Make sure signatures match
4501             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4502                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
4503             if (!match) {
4504                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
4505                         == PackageManager.SIGNATURE_MATCH;
4506             }
4507             if (!match) {
4508                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
4509                         == PackageManager.SIGNATURE_MATCH;
4510             }
4511             if (!match) {
4512                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
4513                         "Package " + pkg.packageName
4514                         + " has no signatures that match those in shared user "
4515                         + pkgSetting.sharedUser.name + "; ignoring!");
4516             }
4517         }
4518     }
4519 
4520     /**
4521      * Enforces that only the system UID or root's UID can call a method exposed
4522      * via Binder.
4523      *
4524      * @param message used as message if SecurityException is thrown
4525      * @throws SecurityException if the caller is not system or root
4526      */
enforceSystemOrRoot(String message)4527     private static final void enforceSystemOrRoot(String message) {
4528         final int uid = Binder.getCallingUid();
4529         if (uid != Process.SYSTEM_UID && uid != 0) {
4530             throw new SecurityException(message);
4531         }
4532     }
4533 
4534     @Override
performBootDexOpt()4535     public void performBootDexOpt() {
4536         enforceSystemOrRoot("Only the system can request dexopt be performed");
4537 
4538         // Before everything else, see whether we need to fstrim.
4539         try {
4540             IMountService ms = PackageHelper.getMountService();
4541             if (ms != null) {
4542                 final boolean isUpgrade = isUpgrade();
4543                 boolean doTrim = isUpgrade;
4544                 if (doTrim) {
4545                     Slog.w(TAG, "Running disk maintenance immediately due to system update");
4546                 } else {
4547                     final long interval = android.provider.Settings.Global.getLong(
4548                             mContext.getContentResolver(),
4549                             android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
4550                             DEFAULT_MANDATORY_FSTRIM_INTERVAL);
4551                     if (interval > 0) {
4552                         final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
4553                         if (timeSinceLast > interval) {
4554                             doTrim = true;
4555                             Slog.w(TAG, "No disk maintenance in " + timeSinceLast
4556                                     + "; running immediately");
4557                         }
4558                     }
4559                 }
4560                 if (doTrim) {
4561                     if (!isFirstBoot()) {
4562                         try {
4563                             ActivityManagerNative.getDefault().showBootMessage(
4564                                     mContext.getResources().getString(
4565                                             R.string.android_upgrading_fstrim), true);
4566                         } catch (RemoteException e) {
4567                         }
4568                     }
4569                     ms.runMaintenance();
4570                 }
4571             } else {
4572                 Slog.e(TAG, "Mount service unavailable!");
4573             }
4574         } catch (RemoteException e) {
4575             // Can't happen; MountService is local
4576         }
4577 
4578         final ArraySet<PackageParser.Package> pkgs;
4579         synchronized (mPackages) {
4580             pkgs = mDeferredDexOpt;
4581             mDeferredDexOpt = null;
4582         }
4583 
4584         if (pkgs != null) {
4585             // Sort apps by importance for dexopt ordering. Important apps are given more priority
4586             // in case the device runs out of space.
4587             ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
4588             // Give priority to core apps.
4589             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4590                 PackageParser.Package pkg = it.next();
4591                 if (pkg.coreApp) {
4592                     if (DEBUG_DEXOPT) {
4593                         Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
4594                     }
4595                     sortedPkgs.add(pkg);
4596                     it.remove();
4597                 }
4598             }
4599             // Give priority to system apps that listen for pre boot complete.
4600             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
4601             ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
4602             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4603                 PackageParser.Package pkg = it.next();
4604                 if (pkgNames.contains(pkg.packageName)) {
4605                     if (DEBUG_DEXOPT) {
4606                         Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
4607                     }
4608                     sortedPkgs.add(pkg);
4609                     it.remove();
4610                 }
4611             }
4612             // Give priority to system apps.
4613             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4614                 PackageParser.Package pkg = it.next();
4615                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4616                     if (DEBUG_DEXOPT) {
4617                         Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
4618                     }
4619                     sortedPkgs.add(pkg);
4620                     it.remove();
4621                 }
4622             }
4623             // Give priority to updated system apps.
4624             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4625                 PackageParser.Package pkg = it.next();
4626                 if (isUpdatedSystemApp(pkg)) {
4627                     if (DEBUG_DEXOPT) {
4628                         Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
4629                     }
4630                     sortedPkgs.add(pkg);
4631                     it.remove();
4632                 }
4633             }
4634             // Give priority to apps that listen for boot complete.
4635             intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
4636             pkgNames = getPackageNamesForIntent(intent);
4637             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4638                 PackageParser.Package pkg = it.next();
4639                 if (pkgNames.contains(pkg.packageName)) {
4640                     if (DEBUG_DEXOPT) {
4641                         Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
4642                     }
4643                     sortedPkgs.add(pkg);
4644                     it.remove();
4645                 }
4646             }
4647             // Filter out packages that aren't recently used.
4648             filterRecentlyUsedApps(pkgs);
4649             // Add all remaining apps.
4650             for (PackageParser.Package pkg : pkgs) {
4651                 if (DEBUG_DEXOPT) {
4652                     Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
4653                 }
4654                 sortedPkgs.add(pkg);
4655             }
4656 
4657             // If we want to be lazy, filter everything that wasn't recently used.
4658             if (mLazyDexOpt) {
4659                 filterRecentlyUsedApps(sortedPkgs);
4660             }
4661 
4662             int i = 0;
4663             int total = sortedPkgs.size();
4664             File dataDir = Environment.getDataDirectory();
4665             long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
4666             if (lowThreshold == 0) {
4667                 throw new IllegalStateException("Invalid low memory threshold");
4668             }
4669             for (PackageParser.Package pkg : sortedPkgs) {
4670                 long usableSpace = dataDir.getUsableSpace();
4671                 if (usableSpace < lowThreshold) {
4672                     Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
4673                     break;
4674                 }
4675                 performBootDexOpt(pkg, ++i, total);
4676             }
4677         }
4678     }
4679 
filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs)4680     private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
4681         // Filter out packages that aren't recently used.
4682         //
4683         // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
4684         // should do a full dexopt.
4685         if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
4686             int total = pkgs.size();
4687             int skipped = 0;
4688             long now = System.currentTimeMillis();
4689             for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
4690                 PackageParser.Package pkg = i.next();
4691                 long then = pkg.mLastPackageUsageTimeInMills;
4692                 if (then + mDexOptLRUThresholdInMills < now) {
4693                     if (DEBUG_DEXOPT) {
4694                         Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
4695                               ((then == 0) ? "never" : new Date(then)));
4696                     }
4697                     i.remove();
4698                     skipped++;
4699                 }
4700             }
4701             if (DEBUG_DEXOPT) {
4702                 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
4703             }
4704         }
4705     }
4706 
getPackageNamesForIntent(Intent intent)4707     private ArraySet<String> getPackageNamesForIntent(Intent intent) {
4708         List<ResolveInfo> ris = null;
4709         try {
4710             ris = AppGlobals.getPackageManager().queryIntentReceivers(
4711                     intent, null, 0, UserHandle.USER_OWNER);
4712         } catch (RemoteException e) {
4713         }
4714         ArraySet<String> pkgNames = new ArraySet<String>();
4715         if (ris != null) {
4716             for (ResolveInfo ri : ris) {
4717                 pkgNames.add(ri.activityInfo.packageName);
4718             }
4719         }
4720         return pkgNames;
4721     }
4722 
performBootDexOpt(PackageParser.Package pkg, int curr, int total)4723     private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
4724         if (DEBUG_DEXOPT) {
4725             Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
4726         }
4727         if (!isFirstBoot()) {
4728             try {
4729                 ActivityManagerNative.getDefault().showBootMessage(
4730                         mContext.getResources().getString(R.string.android_upgrading_apk,
4731                                 curr, total), true);
4732             } catch (RemoteException e) {
4733             }
4734         }
4735         PackageParser.Package p = pkg;
4736         synchronized (mInstallLock) {
4737             performDexOptLI(p, null /* instruction sets */, false /* force dex */,
4738                             false /* defer */, true /* include dependencies */);
4739         }
4740     }
4741 
4742     @Override
performDexOptIfNeeded(String packageName, String instructionSet)4743     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
4744         return performDexOpt(packageName, instructionSet, false);
4745     }
4746 
getPrimaryInstructionSet(ApplicationInfo info)4747     private static String getPrimaryInstructionSet(ApplicationInfo info) {
4748         if (info.primaryCpuAbi == null) {
4749             return getPreferredInstructionSet();
4750         }
4751 
4752         return VMRuntime.getInstructionSet(info.primaryCpuAbi);
4753     }
4754 
performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt)4755     public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
4756         boolean dexopt = mLazyDexOpt || backgroundDexopt;
4757         boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
4758         if (!dexopt && !updateUsage) {
4759             // We aren't going to dexopt or update usage, so bail early.
4760             return false;
4761         }
4762         PackageParser.Package p;
4763         final String targetInstructionSet;
4764         synchronized (mPackages) {
4765             p = mPackages.get(packageName);
4766             if (p == null) {
4767                 return false;
4768             }
4769             if (updateUsage) {
4770                 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
4771             }
4772             mPackageUsage.write(false);
4773             if (!dexopt) {
4774                 // We aren't going to dexopt, so bail early.
4775                 return false;
4776             }
4777 
4778             targetInstructionSet = instructionSet != null ? instructionSet :
4779                     getPrimaryInstructionSet(p.applicationInfo);
4780             if (p.mDexOptPerformed.contains(targetInstructionSet)) {
4781                 return false;
4782             }
4783         }
4784 
4785         synchronized (mInstallLock) {
4786             final String[] instructionSets = new String[] { targetInstructionSet };
4787             return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
4788                     true /* include dependencies */) == DEX_OPT_PERFORMED;
4789         }
4790     }
4791 
getPackagesThatNeedDexOpt()4792     public ArraySet<String> getPackagesThatNeedDexOpt() {
4793         ArraySet<String> pkgs = null;
4794         synchronized (mPackages) {
4795             for (PackageParser.Package p : mPackages.values()) {
4796                 if (DEBUG_DEXOPT) {
4797                     Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
4798                 }
4799                 if (!p.mDexOptPerformed.isEmpty()) {
4800                     continue;
4801                 }
4802                 if (pkgs == null) {
4803                     pkgs = new ArraySet<String>();
4804                 }
4805                 pkgs.add(p.packageName);
4806             }
4807         }
4808         return pkgs;
4809     }
4810 
shutdown()4811     public void shutdown() {
4812         mPackageUsage.write(true);
4813     }
4814 
performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets, boolean forceDex, boolean defer, ArraySet<String> done)4815     private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
4816              boolean forceDex, boolean defer, ArraySet<String> done) {
4817         for (int i=0; i<libs.size(); i++) {
4818             PackageParser.Package libPkg;
4819             String libName;
4820             synchronized (mPackages) {
4821                 libName = libs.get(i);
4822                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
4823                 if (lib != null && lib.apk != null) {
4824                     libPkg = mPackages.get(lib.apk);
4825                 } else {
4826                     libPkg = null;
4827                 }
4828             }
4829             if (libPkg != null && !done.contains(libName)) {
4830                 performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
4831             }
4832         }
4833     }
4834 
4835     static final int DEX_OPT_SKIPPED = 0;
4836     static final int DEX_OPT_PERFORMED = 1;
4837     static final int DEX_OPT_DEFERRED = 2;
4838     static final int DEX_OPT_FAILED = -1;
4839 
performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, boolean forceDex, boolean defer, ArraySet<String> done)4840     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
4841             boolean forceDex, boolean defer, ArraySet<String> done) {
4842         final String[] instructionSets = targetInstructionSets != null ?
4843                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
4844 
4845         if (done != null) {
4846             done.add(pkg.packageName);
4847             if (pkg.usesLibraries != null) {
4848                 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
4849             }
4850             if (pkg.usesOptionalLibraries != null) {
4851                 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
4852             }
4853         }
4854 
4855         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
4856             return DEX_OPT_SKIPPED;
4857         }
4858 
4859         final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
4860 
4861         final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
4862         boolean performedDexOpt = false;
4863         // There are three basic cases here:
4864         // 1.) we need to dexopt, either because we are forced or it is needed
4865         // 2.) we are defering a needed dexopt
4866         // 3.) we are skipping an unneeded dexopt
4867         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
4868         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4869             if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
4870                 continue;
4871             }
4872 
4873             for (String path : paths) {
4874                 try {
4875                     // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
4876                     // patckage or the one we find does not match the image checksum (i.e. it was
4877                     // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
4878                     // odex file and it matches the checksum of the image but not its base address,
4879                     // meaning we need to move it.
4880                     final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
4881                             pkg.packageName, dexCodeInstructionSet, defer);
4882                     if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
4883                         Log.i(TAG, "Running dexopt on: " + path + " pkg="
4884                                 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
4885                                 + " vmSafeMode=" + vmSafeMode);
4886                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4887                         final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
4888                                 pkg.packageName, dexCodeInstructionSet, vmSafeMode);
4889 
4890                         if (ret < 0) {
4891                             // Don't bother running dexopt again if we failed, it will probably
4892                             // just result in an error again. Also, don't bother dexopting for other
4893                             // paths & ISAs.
4894                             return DEX_OPT_FAILED;
4895                         }
4896 
4897                         performedDexOpt = true;
4898                     } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
4899                         Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
4900                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4901                         final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
4902                                 pkg.packageName, dexCodeInstructionSet);
4903 
4904                         if (ret < 0) {
4905                             // Don't bother running patchoat again if we failed, it will probably
4906                             // just result in an error again. Also, don't bother dexopting for other
4907                             // paths & ISAs.
4908                             return DEX_OPT_FAILED;
4909                         }
4910 
4911                         performedDexOpt = true;
4912                     }
4913 
4914                     // We're deciding to defer a needed dexopt. Don't bother dexopting for other
4915                     // paths and instruction sets. We'll deal with them all together when we process
4916                     // our list of deferred dexopts.
4917                     if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
4918                         if (mDeferredDexOpt == null) {
4919                             mDeferredDexOpt = new ArraySet<PackageParser.Package>();
4920                         }
4921                         mDeferredDexOpt.add(pkg);
4922                         return DEX_OPT_DEFERRED;
4923                     }
4924                 } catch (FileNotFoundException e) {
4925                     Slog.w(TAG, "Apk not found for dexopt: " + path);
4926                     return DEX_OPT_FAILED;
4927                 } catch (IOException e) {
4928                     Slog.w(TAG, "IOException reading apk: " + path, e);
4929                     return DEX_OPT_FAILED;
4930                 } catch (StaleDexCacheError e) {
4931                     Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
4932                     return DEX_OPT_FAILED;
4933                 } catch (Exception e) {
4934                     Slog.w(TAG, "Exception when doing dexopt : ", e);
4935                     return DEX_OPT_FAILED;
4936                 }
4937             }
4938 
4939             // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
4940             // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
4941             // it isn't required. We therefore mark that this package doesn't need dexopt unless
4942             // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
4943             // it.
4944             pkg.mDexOptPerformed.add(dexCodeInstructionSet);
4945         }
4946 
4947         // If we've gotten here, we're sure that no error occurred and that we haven't
4948         // deferred dex-opt. We've either dex-opted one more paths or instruction sets or
4949         // we've skipped all of them because they are up to date. In both cases this
4950         // package doesn't need dexopt any longer.
4951         return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
4952     }
4953 
getAppDexInstructionSets(ApplicationInfo info)4954     private static String[] getAppDexInstructionSets(ApplicationInfo info) {
4955         if (info.primaryCpuAbi != null) {
4956             if (info.secondaryCpuAbi != null) {
4957                 return new String[] {
4958                         VMRuntime.getInstructionSet(info.primaryCpuAbi),
4959                         VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
4960             } else {
4961                 return new String[] {
4962                         VMRuntime.getInstructionSet(info.primaryCpuAbi) };
4963             }
4964         }
4965 
4966         return new String[] { getPreferredInstructionSet() };
4967     }
4968 
getAppDexInstructionSets(PackageSetting ps)4969     private static String[] getAppDexInstructionSets(PackageSetting ps) {
4970         if (ps.primaryCpuAbiString != null) {
4971             if (ps.secondaryCpuAbiString != null) {
4972                 return new String[] {
4973                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
4974                         VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
4975             } else {
4976                 return new String[] {
4977                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
4978             }
4979         }
4980 
4981         return new String[] { getPreferredInstructionSet() };
4982     }
4983 
getPreferredInstructionSet()4984     private static String getPreferredInstructionSet() {
4985         if (sPreferredInstructionSet == null) {
4986             sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
4987         }
4988 
4989         return sPreferredInstructionSet;
4990     }
4991 
getAllInstructionSets()4992     private static List<String> getAllInstructionSets() {
4993         final String[] allAbis = Build.SUPPORTED_ABIS;
4994         final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
4995 
4996         for (String abi : allAbis) {
4997             final String instructionSet = VMRuntime.getInstructionSet(abi);
4998             if (!allInstructionSets.contains(instructionSet)) {
4999                 allInstructionSets.add(instructionSet);
5000             }
5001         }
5002 
5003         return allInstructionSets;
5004     }
5005 
5006     /**
5007      * Returns the instruction set that should be used to compile dex code. In the presence of
5008      * a native bridge this might be different than the one shared libraries use.
5009      */
getDexCodeInstructionSet(String sharedLibraryIsa)5010     private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
5011         String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
5012         return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
5013     }
5014 
getDexCodeInstructionSets(String[] instructionSets)5015     private static String[] getDexCodeInstructionSets(String[] instructionSets) {
5016         ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length);
5017         for (String instructionSet : instructionSets) {
5018             dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
5019         }
5020         return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
5021     }
5022 
5023     /**
5024      * Returns deduplicated list of supported instructions for dex code.
5025      */
getAllDexCodeInstructionSets()5026     public static String[] getAllDexCodeInstructionSets() {
5027         String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
5028         for (int i = 0; i < supportedInstructionSets.length; i++) {
5029             String abi = Build.SUPPORTED_ABIS[i];
5030             supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
5031         }
5032         return getDexCodeInstructionSets(supportedInstructionSets);
5033     }
5034 
5035     @Override
forceDexOpt(String packageName)5036     public void forceDexOpt(String packageName) {
5037         enforceSystemOrRoot("forceDexOpt");
5038 
5039         PackageParser.Package pkg;
5040         synchronized (mPackages) {
5041             pkg = mPackages.get(packageName);
5042             if (pkg == null) {
5043                 throw new IllegalArgumentException("Missing package: " + packageName);
5044             }
5045         }
5046 
5047         synchronized (mInstallLock) {
5048             final String[] instructionSets = new String[] {
5049                     getPrimaryInstructionSet(pkg.applicationInfo) };
5050             final int res = performDexOptLI(pkg, instructionSets, true, false, true);
5051             if (res != DEX_OPT_PERFORMED) {
5052                 throw new IllegalStateException("Failed to dexopt: " + res);
5053             }
5054         }
5055     }
5056 
performDexOptLI(PackageParser.Package pkg, String[] instructionSets, boolean forceDex, boolean defer, boolean inclDependencies)5057     private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets,
5058                                 boolean forceDex, boolean defer, boolean inclDependencies) {
5059         ArraySet<String> done;
5060         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
5061             done = new ArraySet<String>();
5062             done.add(pkg.packageName);
5063         } else {
5064             done = null;
5065         }
5066         return performDexOptLI(pkg, instructionSets,  forceDex, defer, done);
5067     }
5068 
verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)5069     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
5070         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5071             Slog.w(TAG, "Unable to update from " + oldPkg.name
5072                     + " to " + newPkg.packageName
5073                     + ": old package not in system partition");
5074             return false;
5075         } else if (mPackages.get(oldPkg.name) != null) {
5076             Slog.w(TAG, "Unable to update from " + oldPkg.name
5077                     + " to " + newPkg.packageName
5078                     + ": old package still exists");
5079             return false;
5080         }
5081         return true;
5082     }
5083 
getDataPathForUser(int userId)5084     File getDataPathForUser(int userId) {
5085         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
5086     }
5087 
getDataPathForPackage(String packageName, int userId)5088     private File getDataPathForPackage(String packageName, int userId) {
5089         /*
5090          * Until we fully support multiple users, return the directory we
5091          * previously would have. The PackageManagerTests will need to be
5092          * revised when this is changed back..
5093          */
5094         if (userId == 0) {
5095             return new File(mAppDataDir, packageName);
5096         } else {
5097             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
5098                 + File.separator + packageName);
5099         }
5100     }
5101 
createDataDirsLI(String packageName, int uid, String seinfo)5102     private int createDataDirsLI(String packageName, int uid, String seinfo) {
5103         int[] users = sUserManager.getUserIds();
5104         int res = mInstaller.install(packageName, uid, uid, seinfo);
5105         if (res < 0) {
5106             return res;
5107         }
5108         for (int user : users) {
5109             if (user != 0) {
5110                 res = mInstaller.createUserData(packageName,
5111                         UserHandle.getUid(user, uid), user, seinfo);
5112                 if (res < 0) {
5113                     return res;
5114                 }
5115             }
5116         }
5117         return res;
5118     }
5119 
removeDataDirsLI(String packageName)5120     private int removeDataDirsLI(String packageName) {
5121         int[] users = sUserManager.getUserIds();
5122         int res = 0;
5123         for (int user : users) {
5124             int resInner = mInstaller.remove(packageName, user);
5125             if (resInner < 0) {
5126                 res = resInner;
5127             }
5128         }
5129 
5130         return res;
5131     }
5132 
deleteCodeCacheDirsLI(String packageName)5133     private int deleteCodeCacheDirsLI(String packageName) {
5134         int[] users = sUserManager.getUserIds();
5135         int res = 0;
5136         for (int user : users) {
5137             int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
5138             if (resInner < 0) {
5139                 res = resInner;
5140             }
5141         }
5142         return res;
5143     }
5144 
addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, PackageParser.Package changingLib)5145     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
5146             PackageParser.Package changingLib) {
5147         if (file.path != null) {
5148             usesLibraryFiles.add(file.path);
5149             return;
5150         }
5151         PackageParser.Package p = mPackages.get(file.apk);
5152         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
5153             // If we are doing this while in the middle of updating a library apk,
5154             // then we need to make sure to use that new apk for determining the
5155             // dependencies here.  (We haven't yet finished committing the new apk
5156             // to the package manager state.)
5157             if (p == null || p.packageName.equals(changingLib.packageName)) {
5158                 p = changingLib;
5159             }
5160         }
5161         if (p != null) {
5162             usesLibraryFiles.addAll(p.getAllCodePaths());
5163         }
5164     }
5165 
updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)5166     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
5167             PackageParser.Package changingLib) throws PackageManagerException {
5168         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
5169             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
5170             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
5171             for (int i=0; i<N; i++) {
5172                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
5173                 if (file == null) {
5174                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
5175                             "Package " + pkg.packageName + " requires unavailable shared library "
5176                             + pkg.usesLibraries.get(i) + "; failing!");
5177                 }
5178                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5179             }
5180             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
5181             for (int i=0; i<N; i++) {
5182                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
5183                 if (file == null) {
5184                     Slog.w(TAG, "Package " + pkg.packageName
5185                             + " desires unavailable shared library "
5186                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
5187                 } else {
5188                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5189                 }
5190             }
5191             N = usesLibraryFiles.size();
5192             if (N > 0) {
5193                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
5194             } else {
5195                 pkg.usesLibraryFiles = null;
5196             }
5197         }
5198     }
5199 
hasString(List<String> list, List<String> which)5200     private static boolean hasString(List<String> list, List<String> which) {
5201         if (list == null) {
5202             return false;
5203         }
5204         for (int i=list.size()-1; i>=0; i--) {
5205             for (int j=which.size()-1; j>=0; j--) {
5206                 if (which.get(j).equals(list.get(i))) {
5207                     return true;
5208                 }
5209             }
5210         }
5211         return false;
5212     }
5213 
updateAllSharedLibrariesLPw()5214     private void updateAllSharedLibrariesLPw() {
5215         for (PackageParser.Package pkg : mPackages.values()) {
5216             try {
5217                 updateSharedLibrariesLPw(pkg, null);
5218             } catch (PackageManagerException e) {
5219                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5220             }
5221         }
5222     }
5223 
updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)5224     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
5225             PackageParser.Package changingPkg) {
5226         ArrayList<PackageParser.Package> res = null;
5227         for (PackageParser.Package pkg : mPackages.values()) {
5228             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
5229                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
5230                 if (res == null) {
5231                     res = new ArrayList<PackageParser.Package>();
5232                 }
5233                 res.add(pkg);
5234                 try {
5235                     updateSharedLibrariesLPw(pkg, changingPkg);
5236                 } catch (PackageManagerException e) {
5237                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5238                 }
5239             }
5240         }
5241         return res;
5242     }
5243 
5244     /**
5245      * Derive the value of the {@code cpuAbiOverride} based on the provided
5246      * value and an optional stored value from the package settings.
5247      */
deriveAbiOverride(String abiOverride, PackageSetting settings)5248     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
5249         String cpuAbiOverride = null;
5250 
5251         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
5252             cpuAbiOverride = null;
5253         } else if (abiOverride != null) {
5254             cpuAbiOverride = abiOverride;
5255         } else if (settings != null) {
5256             cpuAbiOverride = settings.cpuAbiOverrideString;
5257         }
5258 
5259         return cpuAbiOverride;
5260     }
5261 
scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)5262     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
5263             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5264         boolean success = false;
5265         try {
5266             final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
5267                     currentTime, user);
5268             success = true;
5269             return res;
5270         } finally {
5271             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5272                 removeDataDirsLI(pkg.packageName);
5273             }
5274         }
5275     }
5276 
scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)5277     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
5278             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5279         final File scanFile = new File(pkg.codePath);
5280         if (pkg.applicationInfo.getCodePath() == null ||
5281                 pkg.applicationInfo.getResourcePath() == null) {
5282             // Bail out. The resource and code paths haven't been set.
5283             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
5284                     "Code and resource paths haven't been set correctly");
5285         }
5286 
5287         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5288             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
5289         } else {
5290             // Only allow system apps to be flagged as core apps.
5291             pkg.coreApp = false;
5292         }
5293 
5294         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
5295             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
5296         }
5297 
5298         if (mCustomResolverComponentName != null &&
5299                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
5300             setUpCustomResolverActivity(pkg);
5301         }
5302 
5303         if (pkg.packageName.equals("android")) {
5304             synchronized (mPackages) {
5305                 if (mAndroidApplication != null) {
5306                     Slog.w(TAG, "*************************************************");
5307                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
5308                     Slog.w(TAG, " file=" + scanFile);
5309                     Slog.w(TAG, "*************************************************");
5310                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5311                             "Core android package being redefined.  Skipping.");
5312                 }
5313 
5314                 // Set up information for our fall-back user intent resolution activity.
5315                 mPlatformPackage = pkg;
5316                 pkg.mVersionCode = mSdkVersion;
5317                 mAndroidApplication = pkg.applicationInfo;
5318 
5319                 if (!mResolverReplaced) {
5320                     mResolveActivity.applicationInfo = mAndroidApplication;
5321                     mResolveActivity.name = ResolverActivity.class.getName();
5322                     mResolveActivity.packageName = mAndroidApplication.packageName;
5323                     mResolveActivity.processName = "system:ui";
5324                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5325                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
5326                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
5327                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
5328                     mResolveActivity.exported = true;
5329                     mResolveActivity.enabled = true;
5330                     mResolveInfo.activityInfo = mResolveActivity;
5331                     mResolveInfo.priority = 0;
5332                     mResolveInfo.preferredOrder = 0;
5333                     mResolveInfo.match = 0;
5334                     mResolveComponentName = new ComponentName(
5335                             mAndroidApplication.packageName, mResolveActivity.name);
5336                 }
5337             }
5338         }
5339 
5340         if (DEBUG_PACKAGE_SCANNING) {
5341             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5342                 Log.d(TAG, "Scanning package " + pkg.packageName);
5343         }
5344 
5345         if (mPackages.containsKey(pkg.packageName)
5346                 || mSharedLibraries.containsKey(pkg.packageName)) {
5347             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5348                     "Application package " + pkg.packageName
5349                     + " already installed.  Skipping duplicate.");
5350         }
5351 
5352         // Initialize package source and resource directories
5353         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
5354         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
5355 
5356         SharedUserSetting suid = null;
5357         PackageSetting pkgSetting = null;
5358 
5359         if (!isSystemApp(pkg)) {
5360             // Only system apps can use these features.
5361             pkg.mOriginalPackages = null;
5362             pkg.mRealPackage = null;
5363             pkg.mAdoptPermissions = null;
5364         }
5365 
5366         // writer
5367         synchronized (mPackages) {
5368             if (pkg.mSharedUserId != null) {
5369                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
5370                 if (suid == null) {
5371                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5372                             "Creating application package " + pkg.packageName
5373                             + " for shared user failed");
5374                 }
5375                 if (DEBUG_PACKAGE_SCANNING) {
5376                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5377                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
5378                                 + "): packages=" + suid.packages);
5379                 }
5380             }
5381 
5382             // Check if we are renaming from an original package name.
5383             PackageSetting origPackage = null;
5384             String realName = null;
5385             if (pkg.mOriginalPackages != null) {
5386                 // This package may need to be renamed to a previously
5387                 // installed name.  Let's check on that...
5388                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
5389                 if (pkg.mOriginalPackages.contains(renamed)) {
5390                     // This package had originally been installed as the
5391                     // original name, and we have already taken care of
5392                     // transitioning to the new one.  Just update the new
5393                     // one to continue using the old name.
5394                     realName = pkg.mRealPackage;
5395                     if (!pkg.packageName.equals(renamed)) {
5396                         // Callers into this function may have already taken
5397                         // care of renaming the package; only do it here if
5398                         // it is not already done.
5399                         pkg.setPackageName(renamed);
5400                     }
5401 
5402                 } else {
5403                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
5404                         if ((origPackage = mSettings.peekPackageLPr(
5405                                 pkg.mOriginalPackages.get(i))) != null) {
5406                             // We do have the package already installed under its
5407                             // original name...  should we use it?
5408                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
5409                                 // New package is not compatible with original.
5410                                 origPackage = null;
5411                                 continue;
5412                             } else if (origPackage.sharedUser != null) {
5413                                 // Make sure uid is compatible between packages.
5414                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
5415                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
5416                                             + " to " + pkg.packageName + ": old uid "
5417                                             + origPackage.sharedUser.name
5418                                             + " differs from " + pkg.mSharedUserId);
5419                                     origPackage = null;
5420                                     continue;
5421                                 }
5422                             } else {
5423                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
5424                                         + pkg.packageName + " to old name " + origPackage.name);
5425                             }
5426                             break;
5427                         }
5428                     }
5429                 }
5430             }
5431 
5432             if (mTransferedPackages.contains(pkg.packageName)) {
5433                 Slog.w(TAG, "Package " + pkg.packageName
5434                         + " was transferred to another, but its .apk remains");
5435             }
5436 
5437             // Just create the setting, don't add it yet. For already existing packages
5438             // the PkgSetting exists already and doesn't have to be created.
5439             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
5440                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
5441                     pkg.applicationInfo.primaryCpuAbi,
5442                     pkg.applicationInfo.secondaryCpuAbi,
5443                     pkg.applicationInfo.flags, user, false);
5444             if (pkgSetting == null) {
5445                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5446                         "Creating application package " + pkg.packageName + " failed");
5447             }
5448 
5449             if (pkgSetting.origPackage != null) {
5450                 // If we are first transitioning from an original package,
5451                 // fix up the new package's name now.  We need to do this after
5452                 // looking up the package under its new name, so getPackageLP
5453                 // can take care of fiddling things correctly.
5454                 pkg.setPackageName(origPackage.name);
5455 
5456                 // File a report about this.
5457                 String msg = "New package " + pkgSetting.realName
5458                         + " renamed to replace old package " + pkgSetting.name;
5459                 reportSettingsProblem(Log.WARN, msg);
5460 
5461                 // Make a note of it.
5462                 mTransferedPackages.add(origPackage.name);
5463 
5464                 // No longer need to retain this.
5465                 pkgSetting.origPackage = null;
5466             }
5467 
5468             if (realName != null) {
5469                 // Make a note of it.
5470                 mTransferedPackages.add(pkg.packageName);
5471             }
5472 
5473             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
5474                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
5475             }
5476 
5477             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5478                 // Check all shared libraries and map to their actual file path.
5479                 // We only do this here for apps not on a system dir, because those
5480                 // are the only ones that can fail an install due to this.  We
5481                 // will take care of the system apps by updating all of their
5482                 // library paths after the scan is done.
5483                 updateSharedLibrariesLPw(pkg, null);
5484             }
5485 
5486             if (mFoundPolicyFile) {
5487                 SELinuxMMAC.assignSeinfoValue(pkg);
5488             }
5489 
5490             pkg.applicationInfo.uid = pkgSetting.appId;
5491             pkg.mExtras = pkgSetting;
5492             if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
5493                 try {
5494                     verifySignaturesLP(pkgSetting, pkg);
5495                     // We just determined the app is signed correctly, so bring
5496                     // over the latest parsed certs.
5497                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
5498                 } catch (PackageManagerException e) {
5499                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5500                         throw e;
5501                     }
5502                     // The signature has changed, but this package is in the system
5503                     // image...  let's recover!
5504                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
5505                     // However...  if this package is part of a shared user, but it
5506                     // doesn't match the signature of the shared user, let's fail.
5507                     // What this means is that you can't change the signatures
5508                     // associated with an overall shared user, which doesn't seem all
5509                     // that unreasonable.
5510                     if (pkgSetting.sharedUser != null) {
5511                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5512                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
5513                             throw new PackageManagerException(
5514                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
5515                                             "Signature mismatch for shared user : "
5516                                             + pkgSetting.sharedUser);
5517                         }
5518                     }
5519                     // File a report about this.
5520                     String msg = "System package " + pkg.packageName
5521                         + " signature changed; retaining data.";
5522                     reportSettingsProblem(Log.WARN, msg);
5523                 }
5524             } else {
5525                 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
5526                     throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5527                             + pkg.packageName + " upgrade keys do not match the "
5528                             + "previously installed version");
5529                 } else {
5530                     // We just determined the app is signed correctly, so bring
5531                     // over the latest parsed certs.
5532                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
5533                 }
5534             }
5535             // Verify that this new package doesn't have any content providers
5536             // that conflict with existing packages.  Only do this if the
5537             // package isn't already installed, since we don't want to break
5538             // things that are installed.
5539             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
5540                 final int N = pkg.providers.size();
5541                 int i;
5542                 for (i=0; i<N; i++) {
5543                     PackageParser.Provider p = pkg.providers.get(i);
5544                     if (p.info.authority != null) {
5545                         String names[] = p.info.authority.split(";");
5546                         for (int j = 0; j < names.length; j++) {
5547                             if (mProvidersByAuthority.containsKey(names[j])) {
5548                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
5549                                 final String otherPackageName =
5550                                         ((other != null && other.getComponentName() != null) ?
5551                                                 other.getComponentName().getPackageName() : "?");
5552                                 throw new PackageManagerException(
5553                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
5554                                                 "Can't install because provider name " + names[j]
5555                                                 + " (in package " + pkg.applicationInfo.packageName
5556                                                 + ") is already used by " + otherPackageName);
5557                             }
5558                         }
5559                     }
5560                 }
5561             }
5562 
5563             if (pkg.mAdoptPermissions != null) {
5564                 // This package wants to adopt ownership of permissions from
5565                 // another package.
5566                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
5567                     final String origName = pkg.mAdoptPermissions.get(i);
5568                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
5569                     if (orig != null) {
5570                         if (verifyPackageUpdateLPr(orig, pkg)) {
5571                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
5572                                     + pkg.packageName);
5573                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
5574                         }
5575                     }
5576                 }
5577             }
5578         }
5579 
5580         final String pkgName = pkg.packageName;
5581 
5582         final long scanFileTime = scanFile.lastModified();
5583         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
5584         pkg.applicationInfo.processName = fixProcessName(
5585                 pkg.applicationInfo.packageName,
5586                 pkg.applicationInfo.processName,
5587                 pkg.applicationInfo.uid);
5588 
5589         File dataPath;
5590         if (mPlatformPackage == pkg) {
5591             // The system package is special.
5592             dataPath = new File(Environment.getDataDirectory(), "system");
5593 
5594             pkg.applicationInfo.dataDir = dataPath.getPath();
5595 
5596         } else {
5597             // This is a normal package, need to make its data directory.
5598             dataPath = getDataPathForPackage(pkg.packageName, 0);
5599 
5600             boolean uidError = false;
5601             if (dataPath.exists()) {
5602                 int currentUid = 0;
5603                 try {
5604                     StructStat stat = Os.stat(dataPath.getPath());
5605                     currentUid = stat.st_uid;
5606                 } catch (ErrnoException e) {
5607                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
5608                 }
5609 
5610                 // If we have mismatched owners for the data path, we have a problem.
5611                 if (currentUid != pkg.applicationInfo.uid) {
5612                     boolean recovered = false;
5613                     if (currentUid == 0) {
5614                         // The directory somehow became owned by root.  Wow.
5615                         // This is probably because the system was stopped while
5616                         // installd was in the middle of messing with its libs
5617                         // directory.  Ask installd to fix that.
5618                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
5619                                 pkg.applicationInfo.uid);
5620                         if (ret >= 0) {
5621                             recovered = true;
5622                             String msg = "Package " + pkg.packageName
5623                                     + " unexpectedly changed to uid 0; recovered to " +
5624                                     + pkg.applicationInfo.uid;
5625                             reportSettingsProblem(Log.WARN, msg);
5626                         }
5627                     }
5628                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5629                             || (scanFlags&SCAN_BOOTING) != 0)) {
5630                         // If this is a system app, we can at least delete its
5631                         // current data so the application will still work.
5632                         int ret = removeDataDirsLI(pkgName);
5633                         if (ret >= 0) {
5634                             // TODO: Kill the processes first
5635                             // Old data gone!
5636                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5637                                     ? "System package " : "Third party package ";
5638                             String msg = prefix + pkg.packageName
5639                                     + " has changed from uid: "
5640                                     + currentUid + " to "
5641                                     + pkg.applicationInfo.uid + "; old data erased";
5642                             reportSettingsProblem(Log.WARN, msg);
5643                             recovered = true;
5644 
5645                             // And now re-install the app.
5646                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5647                                                    pkg.applicationInfo.seinfo);
5648                             if (ret == -1) {
5649                                 // Ack should not happen!
5650                                 msg = prefix + pkg.packageName
5651                                         + " could not have data directory re-created after delete.";
5652                                 reportSettingsProblem(Log.WARN, msg);
5653                                 throw new PackageManagerException(
5654                                         INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
5655                             }
5656                         }
5657                         if (!recovered) {
5658                             mHasSystemUidErrors = true;
5659                         }
5660                     } else if (!recovered) {
5661                         // If we allow this install to proceed, we will be broken.
5662                         // Abort, abort!
5663                         throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
5664                                 "scanPackageLI");
5665                     }
5666                     if (!recovered) {
5667                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
5668                             + pkg.applicationInfo.uid + "/fs_"
5669                             + currentUid;
5670                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
5671                         pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
5672                         String msg = "Package " + pkg.packageName
5673                                 + " has mismatched uid: "
5674                                 + currentUid + " on disk, "
5675                                 + pkg.applicationInfo.uid + " in settings";
5676                         // writer
5677                         synchronized (mPackages) {
5678                             mSettings.mReadMessages.append(msg);
5679                             mSettings.mReadMessages.append('\n');
5680                             uidError = true;
5681                             if (!pkgSetting.uidError) {
5682                                 reportSettingsProblem(Log.ERROR, msg);
5683                             }
5684                         }
5685                     }
5686                 }
5687                 pkg.applicationInfo.dataDir = dataPath.getPath();
5688                 if (mShouldRestoreconData) {
5689                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
5690                     mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
5691                                 pkg.applicationInfo.uid);
5692                 }
5693             } else {
5694                 if (DEBUG_PACKAGE_SCANNING) {
5695                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5696                         Log.v(TAG, "Want this data dir: " + dataPath);
5697                 }
5698                 //invoke installer to do the actual installation
5699                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5700                                            pkg.applicationInfo.seinfo);
5701                 if (ret < 0) {
5702                     // Error from installer
5703                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5704                             "Unable to create data dirs [errorCode=" + ret + "]");
5705                 }
5706 
5707                 if (dataPath.exists()) {
5708                     pkg.applicationInfo.dataDir = dataPath.getPath();
5709                 } else {
5710                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
5711                     pkg.applicationInfo.dataDir = null;
5712                 }
5713             }
5714 
5715             pkgSetting.uidError = uidError;
5716         }
5717 
5718         final String path = scanFile.getPath();
5719         final String codePath = pkg.applicationInfo.getCodePath();
5720         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
5721         if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
5722             setBundledAppAbisAndRoots(pkg, pkgSetting);
5723 
5724             // If we haven't found any native libraries for the app, check if it has
5725             // renderscript code. We'll need to force the app to 32 bit if it has
5726             // renderscript bitcode.
5727             if (pkg.applicationInfo.primaryCpuAbi == null
5728                     && pkg.applicationInfo.secondaryCpuAbi == null
5729                     && Build.SUPPORTED_64_BIT_ABIS.length >  0) {
5730                 NativeLibraryHelper.Handle handle = null;
5731                 try {
5732                     handle = NativeLibraryHelper.Handle.create(scanFile);
5733                     if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5734                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
5735                     }
5736                 } catch (IOException ioe) {
5737                     Slog.w(TAG, "Error scanning system app : " + ioe);
5738                 } finally {
5739                     IoUtils.closeQuietly(handle);
5740                 }
5741             }
5742 
5743             setNativeLibraryPaths(pkg);
5744         } else {
5745             // TODO: We can probably be smarter about this stuff. For installed apps,
5746             // we can calculate this information at install time once and for all. For
5747             // system apps, we can probably assume that this information doesn't change
5748             // after the first boot scan. As things stand, we do lots of unnecessary work.
5749 
5750             // Give ourselves some initial paths; we'll come back for another
5751             // pass once we've determined ABI below.
5752             setNativeLibraryPaths(pkg);
5753 
5754             final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
5755             final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
5756             final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
5757 
5758             NativeLibraryHelper.Handle handle = null;
5759             try {
5760                 handle = NativeLibraryHelper.Handle.create(scanFile);
5761                 // TODO(multiArch): This can be null for apps that didn't go through the
5762                 // usual installation process. We can calculate it again, like we
5763                 // do during install time.
5764                 //
5765                 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
5766                 // unnecessary.
5767                 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
5768 
5769                 // Null out the abis so that they can be recalculated.
5770                 pkg.applicationInfo.primaryCpuAbi = null;
5771                 pkg.applicationInfo.secondaryCpuAbi = null;
5772                 if (isMultiArch(pkg.applicationInfo)) {
5773                     // Warn if we've set an abiOverride for multi-lib packages..
5774                     // By definition, we need to copy both 32 and 64 bit libraries for
5775                     // such packages.
5776                     if (pkg.cpuAbiOverride != null
5777                             && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
5778                         Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
5779                     }
5780 
5781                     int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
5782                     int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
5783                     if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
5784                         if (isAsec) {
5785                             abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
5786                         } else {
5787                             abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5788                                     nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
5789                                     useIsaSpecificSubdirs);
5790                         }
5791                     }
5792 
5793                     maybeThrowExceptionForMultiArchCopy(
5794                             "Error unpackaging 32 bit native libs for multiarch app.", abi32);
5795 
5796                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
5797                         if (isAsec) {
5798                             abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
5799                         } else {
5800                             abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5801                                     nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
5802                                     useIsaSpecificSubdirs);
5803                         }
5804                     }
5805 
5806                     maybeThrowExceptionForMultiArchCopy(
5807                             "Error unpackaging 64 bit native libs for multiarch app.", abi64);
5808 
5809                     if (abi64 >= 0) {
5810                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
5811                     }
5812 
5813                     if (abi32 >= 0) {
5814                         final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
5815                         if (abi64 >= 0) {
5816                             pkg.applicationInfo.secondaryCpuAbi = abi;
5817                         } else {
5818                             pkg.applicationInfo.primaryCpuAbi = abi;
5819                         }
5820                     }
5821                 } else {
5822                     String[] abiList = (cpuAbiOverride != null) ?
5823                             new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
5824 
5825                     // Enable gross and lame hacks for apps that are built with old
5826                     // SDK tools. We must scan their APKs for renderscript bitcode and
5827                     // not launch them if it's present. Don't bother checking on devices
5828                     // that don't have 64 bit support.
5829                     boolean needsRenderScriptOverride = false;
5830                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
5831                             NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5832                         abiList = Build.SUPPORTED_32_BIT_ABIS;
5833                         needsRenderScriptOverride = true;
5834                     }
5835 
5836                     final int copyRet;
5837                     if (isAsec) {
5838                         copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
5839                     } else {
5840                         copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5841                                 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
5842                     }
5843 
5844                     if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
5845                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5846                                 "Error unpackaging native libs for app, errorCode=" + copyRet);
5847                     }
5848 
5849                     if (copyRet >= 0) {
5850                         pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
5851                     } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
5852                         pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
5853                     } else if (needsRenderScriptOverride) {
5854                         pkg.applicationInfo.primaryCpuAbi = abiList[0];
5855                     }
5856                 }
5857             } catch (IOException ioe) {
5858                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
5859             } finally {
5860                 IoUtils.closeQuietly(handle);
5861             }
5862 
5863             // Now that we've calculated the ABIs and determined if it's an internal app,
5864             // we will go ahead and populate the nativeLibraryPath.
5865             setNativeLibraryPaths(pkg);
5866 
5867             if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
5868             final int[] userIds = sUserManager.getUserIds();
5869             synchronized (mInstallLock) {
5870                 // Create a native library symlink only if we have native libraries
5871                 // and if the native libraries are 32 bit libraries. We do not provide
5872                 // this symlink for 64 bit libraries.
5873                 if (pkg.applicationInfo.primaryCpuAbi != null &&
5874                         !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
5875                     final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
5876                     for (int userId : userIds) {
5877                         if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
5878                             throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5879                                     "Failed linking native library dir (user=" + userId + ")");
5880                         }
5881                     }
5882                 }
5883             }
5884         }
5885 
5886         // This is a special case for the "system" package, where the ABI is
5887         // dictated by the zygote configuration (and init.rc). We should keep track
5888         // of this ABI so that we can deal with "normal" applications that run under
5889         // the same UID correctly.
5890         if (mPlatformPackage == pkg) {
5891             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
5892                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
5893         }
5894 
5895         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
5896         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
5897         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
5898         // Copy the derived override back to the parsed package, so that we can
5899         // update the package settings accordingly.
5900         pkg.cpuAbiOverride = cpuAbiOverride;
5901 
5902         if (DEBUG_ABI_SELECTION) {
5903             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
5904                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
5905                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
5906         }
5907 
5908         // Push the derived path down into PackageSettings so we know what to
5909         // clean up at uninstall time.
5910         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
5911 
5912         if (DEBUG_ABI_SELECTION) {
5913             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
5914                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
5915                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
5916         }
5917 
5918         if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
5919             // We don't do this here during boot because we can do it all
5920             // at once after scanning all existing packages.
5921             //
5922             // We also do this *before* we perform dexopt on this package, so that
5923             // we can avoid redundant dexopts, and also to make sure we've got the
5924             // code and package path correct.
5925             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
5926                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
5927         }
5928 
5929         if ((scanFlags & SCAN_NO_DEX) == 0) {
5930             if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
5931                     (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5932                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
5933             }
5934         }
5935 
5936         if (mFactoryTest && pkg.requestedPermissions.contains(
5937                 android.Manifest.permission.FACTORY_TEST)) {
5938             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
5939         }
5940 
5941         ArrayList<PackageParser.Package> clientLibPkgs = null;
5942 
5943         // writer
5944         synchronized (mPackages) {
5945             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5946                 // Only system apps can add new shared libraries.
5947                 if (pkg.libraryNames != null) {
5948                     for (int i=0; i<pkg.libraryNames.size(); i++) {
5949                         String name = pkg.libraryNames.get(i);
5950                         boolean allowed = false;
5951                         if (isUpdatedSystemApp(pkg)) {
5952                             // New library entries can only be added through the
5953                             // system image.  This is important to get rid of a lot
5954                             // of nasty edge cases: for example if we allowed a non-
5955                             // system update of the app to add a library, then uninstalling
5956                             // the update would make the library go away, and assumptions
5957                             // we made such as through app install filtering would now
5958                             // have allowed apps on the device which aren't compatible
5959                             // with it.  Better to just have the restriction here, be
5960                             // conservative, and create many fewer cases that can negatively
5961                             // impact the user experience.
5962                             final PackageSetting sysPs = mSettings
5963                                     .getDisabledSystemPkgLPr(pkg.packageName);
5964                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
5965                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
5966                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
5967                                         allowed = true;
5968                                         allowed = true;
5969                                         break;
5970                                     }
5971                                 }
5972                             }
5973                         } else {
5974                             allowed = true;
5975                         }
5976                         if (allowed) {
5977                             if (!mSharedLibraries.containsKey(name)) {
5978                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
5979                             } else if (!name.equals(pkg.packageName)) {
5980                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
5981                                         + name + " already exists; skipping");
5982                             }
5983                         } else {
5984                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
5985                                     + name + " that is not declared on system image; skipping");
5986                         }
5987                     }
5988                     if ((scanFlags&SCAN_BOOTING) == 0) {
5989                         // If we are not booting, we need to update any applications
5990                         // that are clients of our shared library.  If we are booting,
5991                         // this will all be done once the scan is complete.
5992                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
5993                     }
5994                 }
5995             }
5996         }
5997 
5998         // We also need to dexopt any apps that are dependent on this library.  Note that
5999         // if these fail, we should abort the install since installing the library will
6000         // result in some apps being broken.
6001         if (clientLibPkgs != null) {
6002             if ((scanFlags & SCAN_NO_DEX) == 0) {
6003                 for (int i = 0; i < clientLibPkgs.size(); i++) {
6004                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
6005                     if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
6006                             (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
6007                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
6008                                 "scanPackageLI failed to dexopt clientLibPkgs");
6009                     }
6010                 }
6011             }
6012         }
6013 
6014         // Request the ActivityManager to kill the process(only for existing packages)
6015         // so that we do not end up in a confused state while the user is still using the older
6016         // version of the application while the new one gets installed.
6017         if ((scanFlags & SCAN_REPLACING) != 0) {
6018             killApplication(pkg.applicationInfo.packageName,
6019                         pkg.applicationInfo.uid, "update pkg");
6020         }
6021 
6022         // Also need to kill any apps that are dependent on the library.
6023         if (clientLibPkgs != null) {
6024             for (int i=0; i<clientLibPkgs.size(); i++) {
6025                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
6026                 killApplication(clientPkg.applicationInfo.packageName,
6027                         clientPkg.applicationInfo.uid, "update lib");
6028             }
6029         }
6030 
6031         // writer
6032         synchronized (mPackages) {
6033             // We don't expect installation to fail beyond this point
6034 
6035             // Add the new setting to mSettings
6036             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
6037             // Add the new setting to mPackages
6038             mPackages.put(pkg.applicationInfo.packageName, pkg);
6039             // Make sure we don't accidentally delete its data.
6040             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
6041             while (iter.hasNext()) {
6042                 PackageCleanItem item = iter.next();
6043                 if (pkgName.equals(item.packageName)) {
6044                     iter.remove();
6045                 }
6046             }
6047 
6048             // Take care of first install / last update times.
6049             if (currentTime != 0) {
6050                 if (pkgSetting.firstInstallTime == 0) {
6051                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
6052                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
6053                     pkgSetting.lastUpdateTime = currentTime;
6054                 }
6055             } else if (pkgSetting.firstInstallTime == 0) {
6056                 // We need *something*.  Take time time stamp of the file.
6057                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
6058             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
6059                 if (scanFileTime != pkgSetting.timeStamp) {
6060                     // A package on the system image has changed; consider this
6061                     // to be an update.
6062                     pkgSetting.lastUpdateTime = scanFileTime;
6063                 }
6064             }
6065 
6066             // Add the package's KeySets to the global KeySetManagerService
6067             KeySetManagerService ksms = mSettings.mKeySetManagerService;
6068             try {
6069                 // Old KeySetData no longer valid.
6070                 ksms.removeAppKeySetDataLPw(pkg.packageName);
6071                 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
6072                 if (pkg.mKeySetMapping != null) {
6073                     for (Map.Entry<String, ArraySet<PublicKey>> entry :
6074                             pkg.mKeySetMapping.entrySet()) {
6075                         if (entry.getValue() != null) {
6076                             ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
6077                                                           entry.getValue(), entry.getKey());
6078                         }
6079                     }
6080                     if (pkg.mUpgradeKeySets != null) {
6081                         for (String upgradeAlias : pkg.mUpgradeKeySets) {
6082                             ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
6083                         }
6084                     }
6085                 }
6086             } catch (NullPointerException e) {
6087                 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
6088             } catch (IllegalArgumentException e) {
6089                 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
6090             }
6091 
6092             int N = pkg.providers.size();
6093             StringBuilder r = null;
6094             int i;
6095             for (i=0; i<N; i++) {
6096                 PackageParser.Provider p = pkg.providers.get(i);
6097                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
6098                         p.info.processName, pkg.applicationInfo.uid);
6099                 mProviders.addProvider(p);
6100                 p.syncable = p.info.isSyncable;
6101                 if (p.info.authority != null) {
6102                     String names[] = p.info.authority.split(";");
6103                     p.info.authority = null;
6104                     for (int j = 0; j < names.length; j++) {
6105                         if (j == 1 && p.syncable) {
6106                             // We only want the first authority for a provider to possibly be
6107                             // syncable, so if we already added this provider using a different
6108                             // authority clear the syncable flag. We copy the provider before
6109                             // changing it because the mProviders object contains a reference
6110                             // to a provider that we don't want to change.
6111                             // Only do this for the second authority since the resulting provider
6112                             // object can be the same for all future authorities for this provider.
6113                             p = new PackageParser.Provider(p);
6114                             p.syncable = false;
6115                         }
6116                         if (!mProvidersByAuthority.containsKey(names[j])) {
6117                             mProvidersByAuthority.put(names[j], p);
6118                             if (p.info.authority == null) {
6119                                 p.info.authority = names[j];
6120                             } else {
6121                                 p.info.authority = p.info.authority + ";" + names[j];
6122                             }
6123                             if (DEBUG_PACKAGE_SCANNING) {
6124                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6125                                     Log.d(TAG, "Registered content provider: " + names[j]
6126                                             + ", className = " + p.info.name + ", isSyncable = "
6127                                             + p.info.isSyncable);
6128                             }
6129                         } else {
6130                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6131                             Slog.w(TAG, "Skipping provider name " + names[j] +
6132                                     " (in package " + pkg.applicationInfo.packageName +
6133                                     "): name already used by "
6134                                     + ((other != null && other.getComponentName() != null)
6135                                             ? other.getComponentName().getPackageName() : "?"));
6136                         }
6137                     }
6138                 }
6139                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6140                     if (r == null) {
6141                         r = new StringBuilder(256);
6142                     } else {
6143                         r.append(' ');
6144                     }
6145                     r.append(p.info.name);
6146                 }
6147             }
6148             if (r != null) {
6149                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
6150             }
6151 
6152             N = pkg.services.size();
6153             r = null;
6154             for (i=0; i<N; i++) {
6155                 PackageParser.Service s = pkg.services.get(i);
6156                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
6157                         s.info.processName, pkg.applicationInfo.uid);
6158                 mServices.addService(s);
6159                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6160                     if (r == null) {
6161                         r = new StringBuilder(256);
6162                     } else {
6163                         r.append(' ');
6164                     }
6165                     r.append(s.info.name);
6166                 }
6167             }
6168             if (r != null) {
6169                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
6170             }
6171 
6172             N = pkg.receivers.size();
6173             r = null;
6174             for (i=0; i<N; i++) {
6175                 PackageParser.Activity a = pkg.receivers.get(i);
6176                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6177                         a.info.processName, pkg.applicationInfo.uid);
6178                 mReceivers.addActivity(a, "receiver");
6179                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6180                     if (r == null) {
6181                         r = new StringBuilder(256);
6182                     } else {
6183                         r.append(' ');
6184                     }
6185                     r.append(a.info.name);
6186                 }
6187             }
6188             if (r != null) {
6189                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
6190             }
6191 
6192             N = pkg.activities.size();
6193             r = null;
6194             for (i=0; i<N; i++) {
6195                 PackageParser.Activity a = pkg.activities.get(i);
6196                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6197                         a.info.processName, pkg.applicationInfo.uid);
6198                 mActivities.addActivity(a, "activity");
6199                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6200                     if (r == null) {
6201                         r = new StringBuilder(256);
6202                     } else {
6203                         r.append(' ');
6204                     }
6205                     r.append(a.info.name);
6206                 }
6207             }
6208             if (r != null) {
6209                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
6210             }
6211 
6212             N = pkg.permissionGroups.size();
6213             r = null;
6214             for (i=0; i<N; i++) {
6215                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
6216                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
6217                 if (cur == null) {
6218                     mPermissionGroups.put(pg.info.name, pg);
6219                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6220                         if (r == null) {
6221                             r = new StringBuilder(256);
6222                         } else {
6223                             r.append(' ');
6224                         }
6225                         r.append(pg.info.name);
6226                     }
6227                 } else {
6228                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
6229                             + pg.info.packageName + " ignored: original from "
6230                             + cur.info.packageName);
6231                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6232                         if (r == null) {
6233                             r = new StringBuilder(256);
6234                         } else {
6235                             r.append(' ');
6236                         }
6237                         r.append("DUP:");
6238                         r.append(pg.info.name);
6239                     }
6240                 }
6241             }
6242             if (r != null) {
6243                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
6244             }
6245 
6246             N = pkg.permissions.size();
6247             r = null;
6248             for (i=0; i<N; i++) {
6249                 PackageParser.Permission p = pkg.permissions.get(i);
6250                 ArrayMap<String, BasePermission> permissionMap =
6251                         p.tree ? mSettings.mPermissionTrees
6252                         : mSettings.mPermissions;
6253                 p.group = mPermissionGroups.get(p.info.group);
6254                 if (p.info.group == null || p.group != null) {
6255                     BasePermission bp = permissionMap.get(p.info.name);
6256 
6257                     // Allow system apps to redefine non-system permissions
6258                     if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
6259                         final boolean currentOwnerIsSystem = (bp.perm != null
6260                                 && isSystemApp(bp.perm.owner));
6261                         if (isSystemApp(p.owner)) {
6262                             if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
6263                                 // It's a built-in permission and no owner, take ownership now
6264                                 bp.packageSetting = pkgSetting;
6265                                 bp.perm = p;
6266                                 bp.uid = pkg.applicationInfo.uid;
6267                                 bp.sourcePackage = p.info.packageName;
6268                             } else if (!currentOwnerIsSystem) {
6269                                 String msg = "New decl " + p.owner + " of permission  "
6270                                         + p.info.name + " is system; overriding " + bp.sourcePackage;
6271                                 reportSettingsProblem(Log.WARN, msg);
6272                                 bp = null;
6273                             }
6274                         }
6275                     }
6276 
6277                     if (bp == null) {
6278                         bp = new BasePermission(p.info.name, p.info.packageName,
6279                                 BasePermission.TYPE_NORMAL);
6280                         permissionMap.put(p.info.name, bp);
6281                     }
6282 
6283                     if (bp.perm == null) {
6284                         if (bp.sourcePackage == null
6285                                 || bp.sourcePackage.equals(p.info.packageName)) {
6286                             BasePermission tree = findPermissionTreeLP(p.info.name);
6287                             if (tree == null
6288                                     || tree.sourcePackage.equals(p.info.packageName)) {
6289                                 bp.packageSetting = pkgSetting;
6290                                 bp.perm = p;
6291                                 bp.uid = pkg.applicationInfo.uid;
6292                                 bp.sourcePackage = p.info.packageName;
6293                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6294                                     if (r == null) {
6295                                         r = new StringBuilder(256);
6296                                     } else {
6297                                         r.append(' ');
6298                                     }
6299                                     r.append(p.info.name);
6300                                 }
6301                             } else {
6302                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
6303                                         + p.info.packageName + " ignored: base tree "
6304                                         + tree.name + " is from package "
6305                                         + tree.sourcePackage);
6306                             }
6307                         } else {
6308                             Slog.w(TAG, "Permission " + p.info.name + " from package "
6309                                     + p.info.packageName + " ignored: original from "
6310                                     + bp.sourcePackage);
6311                         }
6312                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6313                         if (r == null) {
6314                             r = new StringBuilder(256);
6315                         } else {
6316                             r.append(' ');
6317                         }
6318                         r.append("DUP:");
6319                         r.append(p.info.name);
6320                     }
6321                     if (bp.perm == p) {
6322                         bp.protectionLevel = p.info.protectionLevel;
6323                     }
6324                 } else {
6325                     Slog.w(TAG, "Permission " + p.info.name + " from package "
6326                             + p.info.packageName + " ignored: no group "
6327                             + p.group);
6328                 }
6329             }
6330             if (r != null) {
6331                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
6332             }
6333 
6334             N = pkg.instrumentation.size();
6335             r = null;
6336             for (i=0; i<N; i++) {
6337                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6338                 a.info.packageName = pkg.applicationInfo.packageName;
6339                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
6340                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
6341                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
6342                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
6343                 a.info.dataDir = pkg.applicationInfo.dataDir;
6344 
6345                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
6346                 // need other information about the application, like the ABI and what not ?
6347                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
6348                 mInstrumentation.put(a.getComponentName(), a);
6349                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6350                     if (r == null) {
6351                         r = new StringBuilder(256);
6352                     } else {
6353                         r.append(' ');
6354                     }
6355                     r.append(a.info.name);
6356                 }
6357             }
6358             if (r != null) {
6359                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
6360             }
6361 
6362             if (pkg.protectedBroadcasts != null) {
6363                 N = pkg.protectedBroadcasts.size();
6364                 for (i=0; i<N; i++) {
6365                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
6366                 }
6367             }
6368 
6369             pkgSetting.setTimeStamp(scanFileTime);
6370 
6371             // Create idmap files for pairs of (packages, overlay packages).
6372             // Note: "android", ie framework-res.apk, is handled by native layers.
6373             if (pkg.mOverlayTarget != null) {
6374                 // This is an overlay package.
6375                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
6376                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
6377                         mOverlays.put(pkg.mOverlayTarget,
6378                                 new ArrayMap<String, PackageParser.Package>());
6379                     }
6380                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
6381                     map.put(pkg.packageName, pkg);
6382                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
6383                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
6384                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6385                                 "scanPackageLI failed to createIdmap");
6386                     }
6387                 }
6388             } else if (mOverlays.containsKey(pkg.packageName) &&
6389                     !pkg.packageName.equals("android")) {
6390                 // This is a regular package, with one or more known overlay packages.
6391                 createIdmapsForPackageLI(pkg);
6392             }
6393         }
6394 
6395         return pkg;
6396     }
6397 
6398     /**
6399      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
6400      * i.e, so that all packages can be run inside a single process if required.
6401      *
6402      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
6403      * this function will either try and make the ABI for all packages in {@code packagesForUser}
6404      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
6405      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
6406      * updating a package that belongs to a shared user.
6407      *
6408      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
6409      * adds unnecessary complexity.
6410      */
adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt)6411     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
6412             PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
6413         String requiredInstructionSet = null;
6414         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
6415             requiredInstructionSet = VMRuntime.getInstructionSet(
6416                      scannedPackage.applicationInfo.primaryCpuAbi);
6417         }
6418 
6419         PackageSetting requirer = null;
6420         for (PackageSetting ps : packagesForUser) {
6421             // If packagesForUser contains scannedPackage, we skip it. This will happen
6422             // when scannedPackage is an update of an existing package. Without this check,
6423             // we will never be able to change the ABI of any package belonging to a shared
6424             // user, even if it's compatible with other packages.
6425             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6426                 if (ps.primaryCpuAbiString == null) {
6427                     continue;
6428                 }
6429 
6430                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
6431                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
6432                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
6433                     // this but there's not much we can do.
6434                     String errorMessage = "Instruction set mismatch, "
6435                             + ((requirer == null) ? "[caller]" : requirer)
6436                             + " requires " + requiredInstructionSet + " whereas " + ps
6437                             + " requires " + instructionSet;
6438                     Slog.w(TAG, errorMessage);
6439                 }
6440 
6441                 if (requiredInstructionSet == null) {
6442                     requiredInstructionSet = instructionSet;
6443                     requirer = ps;
6444                 }
6445             }
6446         }
6447 
6448         if (requiredInstructionSet != null) {
6449             String adjustedAbi;
6450             if (requirer != null) {
6451                 // requirer != null implies that either scannedPackage was null or that scannedPackage
6452                 // did not require an ABI, in which case we have to adjust scannedPackage to match
6453                 // the ABI of the set (which is the same as requirer's ABI)
6454                 adjustedAbi = requirer.primaryCpuAbiString;
6455                 if (scannedPackage != null) {
6456                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
6457                 }
6458             } else {
6459                 // requirer == null implies that we're updating all ABIs in the set to
6460                 // match scannedPackage.
6461                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
6462             }
6463 
6464             for (PackageSetting ps : packagesForUser) {
6465                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6466                     if (ps.primaryCpuAbiString != null) {
6467                         continue;
6468                     }
6469 
6470                     ps.primaryCpuAbiString = adjustedAbi;
6471                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
6472                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
6473                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
6474 
6475                         if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
6476                                 deferDexOpt, true) == DEX_OPT_FAILED) {
6477                             ps.primaryCpuAbiString = null;
6478                             ps.pkg.applicationInfo.primaryCpuAbi = null;
6479                             return;
6480                         } else {
6481                             mInstaller.rmdex(ps.codePathString,
6482                                              getDexCodeInstructionSet(getPreferredInstructionSet()));
6483                         }
6484                     }
6485                 }
6486             }
6487         }
6488     }
6489 
setUpCustomResolverActivity(PackageParser.Package pkg)6490     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
6491         synchronized (mPackages) {
6492             mResolverReplaced = true;
6493             // Set up information for custom user intent resolution activity.
6494             mResolveActivity.applicationInfo = pkg.applicationInfo;
6495             mResolveActivity.name = mCustomResolverComponentName.getClassName();
6496             mResolveActivity.packageName = pkg.applicationInfo.packageName;
6497             mResolveActivity.processName = pkg.applicationInfo.packageName;
6498             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6499             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
6500                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
6501             mResolveActivity.theme = 0;
6502             mResolveActivity.exported = true;
6503             mResolveActivity.enabled = true;
6504             mResolveInfo.activityInfo = mResolveActivity;
6505             mResolveInfo.priority = 0;
6506             mResolveInfo.preferredOrder = 0;
6507             mResolveInfo.match = 0;
6508             mResolveComponentName = mCustomResolverComponentName;
6509             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
6510                     mResolveComponentName);
6511         }
6512     }
6513 
calculateBundledApkRoot(final String codePathString)6514     private static String calculateBundledApkRoot(final String codePathString) {
6515         final File codePath = new File(codePathString);
6516         final File codeRoot;
6517         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
6518             codeRoot = Environment.getRootDirectory();
6519         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
6520             codeRoot = Environment.getOemDirectory();
6521         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
6522             codeRoot = Environment.getVendorDirectory();
6523         } else {
6524             // Unrecognized code path; take its top real segment as the apk root:
6525             // e.g. /something/app/blah.apk => /something
6526             try {
6527                 File f = codePath.getCanonicalFile();
6528                 File parent = f.getParentFile();    // non-null because codePath is a file
6529                 File tmp;
6530                 while ((tmp = parent.getParentFile()) != null) {
6531                     f = parent;
6532                     parent = tmp;
6533                 }
6534                 codeRoot = f;
6535                 Slog.w(TAG, "Unrecognized code path "
6536                         + codePath + " - using " + codeRoot);
6537             } catch (IOException e) {
6538                 // Can't canonicalize the code path -- shenanigans?
6539                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
6540                 return Environment.getRootDirectory().getPath();
6541             }
6542         }
6543         return codeRoot.getPath();
6544     }
6545 
6546     /**
6547      * Derive and set the location of native libraries for the given package,
6548      * which varies depending on where and how the package was installed.
6549      */
setNativeLibraryPaths(PackageParser.Package pkg)6550     private void setNativeLibraryPaths(PackageParser.Package pkg) {
6551         final ApplicationInfo info = pkg.applicationInfo;
6552         final String codePath = pkg.codePath;
6553         final File codeFile = new File(codePath);
6554         final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
6555         final boolean asecApp = isForwardLocked(info) || isExternal(info);
6556 
6557         info.nativeLibraryRootDir = null;
6558         info.nativeLibraryRootRequiresIsa = false;
6559         info.nativeLibraryDir = null;
6560         info.secondaryNativeLibraryDir = null;
6561 
6562         if (isApkFile(codeFile)) {
6563             // Monolithic install
6564             if (bundledApp) {
6565                 // If "/system/lib64/apkname" exists, assume that is the per-package
6566                 // native library directory to use; otherwise use "/system/lib/apkname".
6567                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
6568                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
6569                         getPrimaryInstructionSet(info));
6570 
6571                 // This is a bundled system app so choose the path based on the ABI.
6572                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
6573                 // is just the default path.
6574                 final String apkName = deriveCodePathName(codePath);
6575                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
6576                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
6577                         apkName).getAbsolutePath();
6578 
6579                 if (info.secondaryCpuAbi != null) {
6580                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
6581                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
6582                             secondaryLibDir, apkName).getAbsolutePath();
6583                 }
6584             } else if (asecApp) {
6585                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
6586                         .getAbsolutePath();
6587             } else {
6588                 final String apkName = deriveCodePathName(codePath);
6589                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
6590                         .getAbsolutePath();
6591             }
6592 
6593             info.nativeLibraryRootRequiresIsa = false;
6594             info.nativeLibraryDir = info.nativeLibraryRootDir;
6595         } else {
6596             // Cluster install
6597             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
6598             info.nativeLibraryRootRequiresIsa = true;
6599 
6600             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
6601                     getPrimaryInstructionSet(info)).getAbsolutePath();
6602 
6603             if (info.secondaryCpuAbi != null) {
6604                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
6605                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
6606             }
6607         }
6608     }
6609 
6610     /**
6611      * Calculate the abis and roots for a bundled app. These can uniquely
6612      * be determined from the contents of the system partition, i.e whether
6613      * it contains 64 or 32 bit shared libraries etc. We do not validate any
6614      * of this information, and instead assume that the system was built
6615      * sensibly.
6616      */
setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)6617     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
6618                                            PackageSetting pkgSetting) {
6619         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
6620 
6621         // If "/system/lib64/apkname" exists, assume that is the per-package
6622         // native library directory to use; otherwise use "/system/lib/apkname".
6623         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
6624         setBundledAppAbi(pkg, apkRoot, apkName);
6625         // pkgSetting might be null during rescan following uninstall of updates
6626         // to a bundled app, so accommodate that possibility.  The settings in
6627         // that case will be established later from the parsed package.
6628         //
6629         // If the settings aren't null, sync them up with what we've just derived.
6630         // note that apkRoot isn't stored in the package settings.
6631         if (pkgSetting != null) {
6632             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
6633             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
6634         }
6635     }
6636 
6637     /**
6638      * Deduces the ABI of a bundled app and sets the relevant fields on the
6639      * parsed pkg object.
6640      *
6641      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
6642      *        under which system libraries are installed.
6643      * @param apkName the name of the installed package.
6644      */
setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName)6645     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
6646         final File codeFile = new File(pkg.codePath);
6647 
6648         final boolean has64BitLibs;
6649         final boolean has32BitLibs;
6650         if (isApkFile(codeFile)) {
6651             // Monolithic install
6652             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
6653             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
6654         } else {
6655             // Cluster install
6656             final File rootDir = new File(codeFile, LIB_DIR_NAME);
6657             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
6658                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
6659                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
6660                 has64BitLibs = (new File(rootDir, isa)).exists();
6661             } else {
6662                 has64BitLibs = false;
6663             }
6664             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
6665                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
6666                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
6667                 has32BitLibs = (new File(rootDir, isa)).exists();
6668             } else {
6669                 has32BitLibs = false;
6670             }
6671         }
6672 
6673         if (has64BitLibs && !has32BitLibs) {
6674             // The package has 64 bit libs, but not 32 bit libs. Its primary
6675             // ABI should be 64 bit. We can safely assume here that the bundled
6676             // native libraries correspond to the most preferred ABI in the list.
6677 
6678             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6679             pkg.applicationInfo.secondaryCpuAbi = null;
6680         } else if (has32BitLibs && !has64BitLibs) {
6681             // The package has 32 bit libs but not 64 bit libs. Its primary
6682             // ABI should be 32 bit.
6683 
6684             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6685             pkg.applicationInfo.secondaryCpuAbi = null;
6686         } else if (has32BitLibs && has64BitLibs) {
6687             // The application has both 64 and 32 bit bundled libraries. We check
6688             // here that the app declares multiArch support, and warn if it doesn't.
6689             //
6690             // We will be lenient here and record both ABIs. The primary will be the
6691             // ABI that's higher on the list, i.e, a device that's configured to prefer
6692             // 64 bit apps will see a 64 bit primary ABI,
6693 
6694             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
6695                 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
6696             }
6697 
6698             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
6699                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6700                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6701             } else {
6702                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6703                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6704             }
6705         } else {
6706             pkg.applicationInfo.primaryCpuAbi = null;
6707             pkg.applicationInfo.secondaryCpuAbi = null;
6708         }
6709     }
6710 
killApplication(String pkgName, int appId, String reason)6711     private void killApplication(String pkgName, int appId, String reason) {
6712         // Request the ActivityManager to kill the process(only for existing packages)
6713         // so that we do not end up in a confused state while the user is still using the older
6714         // version of the application while the new one gets installed.
6715         IActivityManager am = ActivityManagerNative.getDefault();
6716         if (am != null) {
6717             try {
6718                 am.killApplicationWithAppId(pkgName, appId, reason);
6719             } catch (RemoteException e) {
6720             }
6721         }
6722     }
6723 
removePackageLI(PackageSetting ps, boolean chatty)6724     void removePackageLI(PackageSetting ps, boolean chatty) {
6725         if (DEBUG_INSTALL) {
6726             if (chatty)
6727                 Log.d(TAG, "Removing package " + ps.name);
6728         }
6729 
6730         // writer
6731         synchronized (mPackages) {
6732             mPackages.remove(ps.name);
6733             final PackageParser.Package pkg = ps.pkg;
6734             if (pkg != null) {
6735                 cleanPackageDataStructuresLILPw(pkg, chatty);
6736             }
6737         }
6738     }
6739 
removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)6740     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
6741         if (DEBUG_INSTALL) {
6742             if (chatty)
6743                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
6744         }
6745 
6746         // writer
6747         synchronized (mPackages) {
6748             mPackages.remove(pkg.applicationInfo.packageName);
6749             cleanPackageDataStructuresLILPw(pkg, chatty);
6750         }
6751     }
6752 
cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)6753     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
6754         int N = pkg.providers.size();
6755         StringBuilder r = null;
6756         int i;
6757         for (i=0; i<N; i++) {
6758             PackageParser.Provider p = pkg.providers.get(i);
6759             mProviders.removeProvider(p);
6760             if (p.info.authority == null) {
6761 
6762                 /* There was another ContentProvider with this authority when
6763                  * this app was installed so this authority is null,
6764                  * Ignore it as we don't have to unregister the provider.
6765                  */
6766                 continue;
6767             }
6768             String names[] = p.info.authority.split(";");
6769             for (int j = 0; j < names.length; j++) {
6770                 if (mProvidersByAuthority.get(names[j]) == p) {
6771                     mProvidersByAuthority.remove(names[j]);
6772                     if (DEBUG_REMOVE) {
6773                         if (chatty)
6774                             Log.d(TAG, "Unregistered content provider: " + names[j]
6775                                     + ", className = " + p.info.name + ", isSyncable = "
6776                                     + p.info.isSyncable);
6777                     }
6778                 }
6779             }
6780             if (DEBUG_REMOVE && chatty) {
6781                 if (r == null) {
6782                     r = new StringBuilder(256);
6783                 } else {
6784                     r.append(' ');
6785                 }
6786                 r.append(p.info.name);
6787             }
6788         }
6789         if (r != null) {
6790             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
6791         }
6792 
6793         N = pkg.services.size();
6794         r = null;
6795         for (i=0; i<N; i++) {
6796             PackageParser.Service s = pkg.services.get(i);
6797             mServices.removeService(s);
6798             if (chatty) {
6799                 if (r == null) {
6800                     r = new StringBuilder(256);
6801                 } else {
6802                     r.append(' ');
6803                 }
6804                 r.append(s.info.name);
6805             }
6806         }
6807         if (r != null) {
6808             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
6809         }
6810 
6811         N = pkg.receivers.size();
6812         r = null;
6813         for (i=0; i<N; i++) {
6814             PackageParser.Activity a = pkg.receivers.get(i);
6815             mReceivers.removeActivity(a, "receiver");
6816             if (DEBUG_REMOVE && chatty) {
6817                 if (r == null) {
6818                     r = new StringBuilder(256);
6819                 } else {
6820                     r.append(' ');
6821                 }
6822                 r.append(a.info.name);
6823             }
6824         }
6825         if (r != null) {
6826             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
6827         }
6828 
6829         N = pkg.activities.size();
6830         r = null;
6831         for (i=0; i<N; i++) {
6832             PackageParser.Activity a = pkg.activities.get(i);
6833             mActivities.removeActivity(a, "activity");
6834             if (DEBUG_REMOVE && chatty) {
6835                 if (r == null) {
6836                     r = new StringBuilder(256);
6837                 } else {
6838                     r.append(' ');
6839                 }
6840                 r.append(a.info.name);
6841             }
6842         }
6843         if (r != null) {
6844             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
6845         }
6846 
6847         N = pkg.permissions.size();
6848         r = null;
6849         for (i=0; i<N; i++) {
6850             PackageParser.Permission p = pkg.permissions.get(i);
6851             BasePermission bp = mSettings.mPermissions.get(p.info.name);
6852             if (bp == null) {
6853                 bp = mSettings.mPermissionTrees.get(p.info.name);
6854             }
6855             if (bp != null && bp.perm == p) {
6856                 bp.perm = null;
6857                 if (DEBUG_REMOVE && chatty) {
6858                     if (r == null) {
6859                         r = new StringBuilder(256);
6860                     } else {
6861                         r.append(' ');
6862                     }
6863                     r.append(p.info.name);
6864                 }
6865             }
6866             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6867                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
6868                 if (appOpPerms != null) {
6869                     appOpPerms.remove(pkg.packageName);
6870                 }
6871             }
6872         }
6873         if (r != null) {
6874             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
6875         }
6876 
6877         N = pkg.requestedPermissions.size();
6878         r = null;
6879         for (i=0; i<N; i++) {
6880             String perm = pkg.requestedPermissions.get(i);
6881             BasePermission bp = mSettings.mPermissions.get(perm);
6882             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6883                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
6884                 if (appOpPerms != null) {
6885                     appOpPerms.remove(pkg.packageName);
6886                     if (appOpPerms.isEmpty()) {
6887                         mAppOpPermissionPackages.remove(perm);
6888                     }
6889                 }
6890             }
6891         }
6892         if (r != null) {
6893             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
6894         }
6895 
6896         N = pkg.instrumentation.size();
6897         r = null;
6898         for (i=0; i<N; i++) {
6899             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6900             mInstrumentation.remove(a.getComponentName());
6901             if (DEBUG_REMOVE && chatty) {
6902                 if (r == null) {
6903                     r = new StringBuilder(256);
6904                 } else {
6905                     r.append(' ');
6906                 }
6907                 r.append(a.info.name);
6908             }
6909         }
6910         if (r != null) {
6911             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
6912         }
6913 
6914         r = null;
6915         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6916             // Only system apps can hold shared libraries.
6917             if (pkg.libraryNames != null) {
6918                 for (i=0; i<pkg.libraryNames.size(); i++) {
6919                     String name = pkg.libraryNames.get(i);
6920                     SharedLibraryEntry cur = mSharedLibraries.get(name);
6921                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
6922                         mSharedLibraries.remove(name);
6923                         if (DEBUG_REMOVE && chatty) {
6924                             if (r == null) {
6925                                 r = new StringBuilder(256);
6926                             } else {
6927                                 r.append(' ');
6928                             }
6929                             r.append(name);
6930                         }
6931                     }
6932                 }
6933             }
6934         }
6935         if (r != null) {
6936             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
6937         }
6938     }
6939 
hasPermission(PackageParser.Package pkgInfo, String perm)6940     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
6941         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
6942             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
6943                 return true;
6944             }
6945         }
6946         return false;
6947     }
6948 
6949     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
6950     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
6951     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
6952 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)6953     private void updatePermissionsLPw(String changingPkg,
6954             PackageParser.Package pkgInfo, int flags) {
6955         // Make sure there are no dangling permission trees.
6956         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
6957         while (it.hasNext()) {
6958             final BasePermission bp = it.next();
6959             if (bp.packageSetting == null) {
6960                 // We may not yet have parsed the package, so just see if
6961                 // we still know about its settings.
6962                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6963             }
6964             if (bp.packageSetting == null) {
6965                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
6966                         + " from package " + bp.sourcePackage);
6967                 it.remove();
6968             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6969                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6970                     Slog.i(TAG, "Removing old permission tree: " + bp.name
6971                             + " from package " + bp.sourcePackage);
6972                     flags |= UPDATE_PERMISSIONS_ALL;
6973                     it.remove();
6974                 }
6975             }
6976         }
6977 
6978         // Make sure all dynamic permissions have been assigned to a package,
6979         // and make sure there are no dangling permissions.
6980         it = mSettings.mPermissions.values().iterator();
6981         while (it.hasNext()) {
6982             final BasePermission bp = it.next();
6983             if (bp.type == BasePermission.TYPE_DYNAMIC) {
6984                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
6985                         + bp.name + " pkg=" + bp.sourcePackage
6986                         + " info=" + bp.pendingInfo);
6987                 if (bp.packageSetting == null && bp.pendingInfo != null) {
6988                     final BasePermission tree = findPermissionTreeLP(bp.name);
6989                     if (tree != null && tree.perm != null) {
6990                         bp.packageSetting = tree.packageSetting;
6991                         bp.perm = new PackageParser.Permission(tree.perm.owner,
6992                                 new PermissionInfo(bp.pendingInfo));
6993                         bp.perm.info.packageName = tree.perm.info.packageName;
6994                         bp.perm.info.name = bp.name;
6995                         bp.uid = tree.uid;
6996                     }
6997                 }
6998             }
6999             if (bp.packageSetting == null) {
7000                 // We may not yet have parsed the package, so just see if
7001                 // we still know about its settings.
7002                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
7003             }
7004             if (bp.packageSetting == null) {
7005                 Slog.w(TAG, "Removing dangling permission: " + bp.name
7006                         + " from package " + bp.sourcePackage);
7007                 it.remove();
7008             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
7009                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
7010                     Slog.i(TAG, "Removing old permission: " + bp.name
7011                             + " from package " + bp.sourcePackage);
7012                     flags |= UPDATE_PERMISSIONS_ALL;
7013                     it.remove();
7014                 }
7015             }
7016         }
7017 
7018         // Now update the permissions for all packages, in particular
7019         // replace the granted permissions of the system packages.
7020         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
7021             for (PackageParser.Package pkg : mPackages.values()) {
7022                 if (pkg != pkgInfo) {
7023                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
7024                             changingPkg);
7025                 }
7026             }
7027         }
7028 
7029         if (pkgInfo != null) {
7030             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
7031         }
7032     }
7033 
grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)7034     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
7035             String packageOfInterest) {
7036         final PackageSetting ps = (PackageSetting) pkg.mExtras;
7037         if (ps == null) {
7038             return;
7039         }
7040         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
7041         ArraySet<String> origPermissions = gp.grantedPermissions;
7042         boolean changedPermission = false;
7043 
7044         if (replace) {
7045             ps.permissionsFixed = false;
7046             if (gp == ps) {
7047                 origPermissions = new ArraySet<String>(gp.grantedPermissions);
7048                 gp.grantedPermissions.clear();
7049                 gp.gids = mGlobalGids;
7050             }
7051         }
7052 
7053         if (gp.gids == null) {
7054             gp.gids = mGlobalGids;
7055         }
7056 
7057         final int N = pkg.requestedPermissions.size();
7058         for (int i=0; i<N; i++) {
7059             final String name = pkg.requestedPermissions.get(i);
7060             final boolean required = pkg.requestedPermissionsRequired.get(i);
7061             final BasePermission bp = mSettings.mPermissions.get(name);
7062             if (DEBUG_INSTALL) {
7063                 if (gp != ps) {
7064                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
7065                 }
7066             }
7067 
7068             if (bp == null || bp.packageSetting == null) {
7069                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7070                     Slog.w(TAG, "Unknown permission " + name
7071                             + " in package " + pkg.packageName);
7072                 }
7073                 continue;
7074             }
7075 
7076             final String perm = bp.name;
7077             boolean allowed;
7078             boolean allowedSig = false;
7079             if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
7080                 // Keep track of app op permissions.
7081                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
7082                 if (pkgs == null) {
7083                     pkgs = new ArraySet<>();
7084                     mAppOpPermissionPackages.put(bp.name, pkgs);
7085                 }
7086                 pkgs.add(pkg.packageName);
7087             }
7088             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
7089             if (level == PermissionInfo.PROTECTION_NORMAL
7090                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
7091                 // We grant a normal or dangerous permission if any of the following
7092                 // are true:
7093                 // 1) The permission is required
7094                 // 2) The permission is optional, but was granted in the past
7095                 // 3) The permission is optional, but was requested by an
7096                 //    app in /system (not /data)
7097                 //
7098                 // Otherwise, reject the permission.
7099                 allowed = (required || origPermissions.contains(perm)
7100                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
7101             } else if (bp.packageSetting == null) {
7102                 // This permission is invalid; skip it.
7103                 allowed = false;
7104             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
7105                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
7106                 if (allowed) {
7107                     allowedSig = true;
7108                 }
7109             } else {
7110                 allowed = false;
7111             }
7112             if (DEBUG_INSTALL) {
7113                 if (gp != ps) {
7114                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
7115                 }
7116             }
7117             if (allowed) {
7118                 if (!isSystemApp(ps) && ps.permissionsFixed) {
7119                     // If this is an existing, non-system package, then
7120                     // we can't add any new permissions to it.
7121                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
7122                         // Except...  if this is a permission that was added
7123                         // to the platform (note: need to only do this when
7124                         // updating the platform).
7125                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
7126                     }
7127                 }
7128                 if (allowed) {
7129                     if (!gp.grantedPermissions.contains(perm)) {
7130                         changedPermission = true;
7131                         gp.grantedPermissions.add(perm);
7132                         gp.gids = appendInts(gp.gids, bp.gids);
7133                     } else if (!ps.haveGids) {
7134                         gp.gids = appendInts(gp.gids, bp.gids);
7135                     }
7136                 } else {
7137                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7138                         Slog.w(TAG, "Not granting permission " + perm
7139                                 + " to package " + pkg.packageName
7140                                 + " because it was previously installed without");
7141                     }
7142                 }
7143             } else {
7144                 if (gp.grantedPermissions.remove(perm)) {
7145                     changedPermission = true;
7146                     gp.gids = removeInts(gp.gids, bp.gids);
7147                     Slog.i(TAG, "Un-granting permission " + perm
7148                             + " from package " + pkg.packageName
7149                             + " (protectionLevel=" + bp.protectionLevel
7150                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7151                             + ")");
7152                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
7153                     // Don't print warning for app op permissions, since it is fine for them
7154                     // not to be granted, there is a UI for the user to decide.
7155                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7156                         Slog.w(TAG, "Not granting permission " + perm
7157                                 + " to package " + pkg.packageName
7158                                 + " (protectionLevel=" + bp.protectionLevel
7159                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7160                                 + ")");
7161                     }
7162                 }
7163             }
7164         }
7165 
7166         if ((changedPermission || replace) && !ps.permissionsFixed &&
7167                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
7168             // This is the first that we have heard about this package, so the
7169             // permissions we have now selected are fixed until explicitly
7170             // changed.
7171             ps.permissionsFixed = true;
7172         }
7173         ps.haveGids = true;
7174     }
7175 
isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)7176     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
7177         boolean allowed = false;
7178         final int NP = PackageParser.NEW_PERMISSIONS.length;
7179         for (int ip=0; ip<NP; ip++) {
7180             final PackageParser.NewPermissionInfo npi
7181                     = PackageParser.NEW_PERMISSIONS[ip];
7182             if (npi.name.equals(perm)
7183                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
7184                 allowed = true;
7185                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
7186                         + pkg.packageName);
7187                 break;
7188             }
7189         }
7190         return allowed;
7191     }
7192 
grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, ArraySet<String> origPermissions)7193     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
7194                                           BasePermission bp, ArraySet<String> origPermissions) {
7195         boolean allowed;
7196         allowed = (compareSignatures(
7197                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
7198                         == PackageManager.SIGNATURE_MATCH)
7199                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
7200                         == PackageManager.SIGNATURE_MATCH);
7201         if (!allowed && (bp.protectionLevel
7202                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
7203             if (isSystemApp(pkg)) {
7204                 // For updated system applications, a system permission
7205                 // is granted only if it had been defined by the original application.
7206                 if (isUpdatedSystemApp(pkg)) {
7207                     final PackageSetting sysPs = mSettings
7208                             .getDisabledSystemPkgLPr(pkg.packageName);
7209                     final GrantedPermissions origGp = sysPs.sharedUser != null
7210                             ? sysPs.sharedUser : sysPs;
7211 
7212                     if (origGp.grantedPermissions.contains(perm)) {
7213                         // If the original was granted this permission, we take
7214                         // that grant decision as read and propagate it to the
7215                         // update.
7216                         if (sysPs.isPrivileged()) {
7217                             allowed = true;
7218                         }
7219                     } else {
7220                         // The system apk may have been updated with an older
7221                         // version of the one on the data partition, but which
7222                         // granted a new system permission that it didn't have
7223                         // before.  In this case we do want to allow the app to
7224                         // now get the new permission if the ancestral apk is
7225                         // privileged to get it.
7226                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
7227                             for (int j=0;
7228                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
7229                                 if (perm.equals(
7230                                         sysPs.pkg.requestedPermissions.get(j))) {
7231                                     allowed = true;
7232                                     break;
7233                                 }
7234                             }
7235                         }
7236                     }
7237                 } else {
7238                     allowed = isPrivilegedApp(pkg);
7239                 }
7240             }
7241         }
7242         if (!allowed && (bp.protectionLevel
7243                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
7244             // For development permissions, a development permission
7245             // is granted only if it was already granted.
7246             allowed = origPermissions.contains(perm);
7247         }
7248         return allowed;
7249     }
7250 
7251     final class ActivityIntentResolver
7252             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)7253         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7254                 boolean defaultOnly, int userId) {
7255             if (!sUserManager.exists(userId)) return null;
7256             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7257             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7258         }
7259 
queryIntent(Intent intent, String resolvedType, int flags, int userId)7260         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7261                 int userId) {
7262             if (!sUserManager.exists(userId)) return null;
7263             mFlags = flags;
7264             return super.queryIntent(intent, resolvedType,
7265                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7266         }
7267 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)7268         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7269                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
7270             if (!sUserManager.exists(userId)) return null;
7271             if (packageActivities == null) {
7272                 return null;
7273             }
7274             mFlags = flags;
7275             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7276             final int N = packageActivities.size();
7277             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
7278                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
7279 
7280             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
7281             for (int i = 0; i < N; ++i) {
7282                 intentFilters = packageActivities.get(i).intents;
7283                 if (intentFilters != null && intentFilters.size() > 0) {
7284                     PackageParser.ActivityIntentInfo[] array =
7285                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
7286                     intentFilters.toArray(array);
7287                     listCut.add(array);
7288                 }
7289             }
7290             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7291         }
7292 
addActivity(PackageParser.Activity a, String type)7293         public final void addActivity(PackageParser.Activity a, String type) {
7294             final boolean systemApp = isSystemApp(a.info.applicationInfo);
7295             mActivities.put(a.getComponentName(), a);
7296             if (DEBUG_SHOW_INFO)
7297                 Log.v(
7298                 TAG, "  " + type + " " +
7299                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
7300             if (DEBUG_SHOW_INFO)
7301                 Log.v(TAG, "    Class=" + a.info.name);
7302             final int NI = a.intents.size();
7303             for (int j=0; j<NI; j++) {
7304                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7305                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
7306                     intent.setPriority(0);
7307                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
7308                             + a.className + " with priority > 0, forcing to 0");
7309                 }
7310                 if (DEBUG_SHOW_INFO) {
7311                     Log.v(TAG, "    IntentFilter:");
7312                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7313                 }
7314                 if (!intent.debugCheck()) {
7315                     Log.w(TAG, "==> For Activity " + a.info.name);
7316                 }
7317                 addFilter(intent);
7318             }
7319         }
7320 
removeActivity(PackageParser.Activity a, String type)7321         public final void removeActivity(PackageParser.Activity a, String type) {
7322             mActivities.remove(a.getComponentName());
7323             if (DEBUG_SHOW_INFO) {
7324                 Log.v(TAG, "  " + type + " "
7325                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
7326                                 : a.info.name) + ":");
7327                 Log.v(TAG, "    Class=" + a.info.name);
7328             }
7329             final int NI = a.intents.size();
7330             for (int j=0; j<NI; j++) {
7331                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7332                 if (DEBUG_SHOW_INFO) {
7333                     Log.v(TAG, "    IntentFilter:");
7334                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7335                 }
7336                 removeFilter(intent);
7337             }
7338         }
7339 
7340         @Override
allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)7341         protected boolean allowFilterResult(
7342                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
7343             ActivityInfo filterAi = filter.activity.info;
7344             for (int i=dest.size()-1; i>=0; i--) {
7345                 ActivityInfo destAi = dest.get(i).activityInfo;
7346                 if (destAi.name == filterAi.name
7347                         && destAi.packageName == filterAi.packageName) {
7348                     return false;
7349                 }
7350             }
7351             return true;
7352         }
7353 
7354         @Override
newArray(int size)7355         protected ActivityIntentInfo[] newArray(int size) {
7356             return new ActivityIntentInfo[size];
7357         }
7358 
7359         @Override
isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)7360         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
7361             if (!sUserManager.exists(userId)) return true;
7362             PackageParser.Package p = filter.activity.owner;
7363             if (p != null) {
7364                 PackageSetting ps = (PackageSetting)p.mExtras;
7365                 if (ps != null) {
7366                     // System apps are never considered stopped for purposes of
7367                     // filtering, because there may be no way for the user to
7368                     // actually re-launch them.
7369                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
7370                             && ps.getStopped(userId);
7371                 }
7372             }
7373             return false;
7374         }
7375 
7376         @Override
isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)7377         protected boolean isPackageForFilter(String packageName,
7378                 PackageParser.ActivityIntentInfo info) {
7379             return packageName.equals(info.activity.owner.packageName);
7380         }
7381 
7382         @Override
newResult(PackageParser.ActivityIntentInfo info, int match, int userId)7383         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
7384                 int match, int userId) {
7385             if (!sUserManager.exists(userId)) return null;
7386             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
7387                 return null;
7388             }
7389             final PackageParser.Activity activity = info.activity;
7390             if (mSafeMode && (activity.info.applicationInfo.flags
7391                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
7392                 return null;
7393             }
7394             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
7395             if (ps == null) {
7396                 return null;
7397             }
7398             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
7399                     ps.readUserState(userId), userId);
7400             if (ai == null) {
7401                 return null;
7402             }
7403             final ResolveInfo res = new ResolveInfo();
7404             res.activityInfo = ai;
7405             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7406                 res.filter = info;
7407             }
7408             res.priority = info.getPriority();
7409             res.preferredOrder = activity.owner.mPreferredOrder;
7410             //System.out.println("Result: " + res.activityInfo.className +
7411             //                   " = " + res.priority);
7412             res.match = match;
7413             res.isDefault = info.hasDefault;
7414             res.labelRes = info.labelRes;
7415             res.nonLocalizedLabel = info.nonLocalizedLabel;
7416             if (userNeedsBadging(userId)) {
7417                 res.noResourceId = true;
7418             } else {
7419                 res.icon = info.icon;
7420             }
7421             res.system = isSystemApp(res.activityInfo.applicationInfo);
7422             return res;
7423         }
7424 
7425         @Override
sortResults(List<ResolveInfo> results)7426         protected void sortResults(List<ResolveInfo> results) {
7427             Collections.sort(results, mResolvePrioritySorter);
7428         }
7429 
7430         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)7431         protected void dumpFilter(PrintWriter out, String prefix,
7432                 PackageParser.ActivityIntentInfo filter) {
7433             out.print(prefix); out.print(
7434                     Integer.toHexString(System.identityHashCode(filter.activity)));
7435                     out.print(' ');
7436                     filter.activity.printComponentShortName(out);
7437                     out.print(" filter ");
7438                     out.println(Integer.toHexString(System.identityHashCode(filter)));
7439         }
7440 
7441         @Override
filterToLabel(PackageParser.ActivityIntentInfo filter)7442         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
7443             return filter.activity;
7444         }
7445 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)7446         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
7447             PackageParser.Activity activity = (PackageParser.Activity)label;
7448             out.print(prefix); out.print(
7449                     Integer.toHexString(System.identityHashCode(activity)));
7450                     out.print(' ');
7451                     activity.printComponentShortName(out);
7452             if (count > 1) {
7453                 out.print(" ("); out.print(count); out.print(" filters)");
7454             }
7455             out.println();
7456         }
7457 
7458 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7459 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7460 //            final List<ResolveInfo> retList = Lists.newArrayList();
7461 //            while (i.hasNext()) {
7462 //                final ResolveInfo resolveInfo = i.next();
7463 //                if (isEnabledLP(resolveInfo.activityInfo)) {
7464 //                    retList.add(resolveInfo);
7465 //                }
7466 //            }
7467 //            return retList;
7468 //        }
7469 
7470         // Keys are String (activity class name), values are Activity.
7471         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
7472                 = new ArrayMap<ComponentName, PackageParser.Activity>();
7473         private int mFlags;
7474     }
7475 
7476     private final class ServiceIntentResolver
7477             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)7478         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7479                 boolean defaultOnly, int userId) {
7480             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7481             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7482         }
7483 
queryIntent(Intent intent, String resolvedType, int flags, int userId)7484         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7485                 int userId) {
7486             if (!sUserManager.exists(userId)) return null;
7487             mFlags = flags;
7488             return super.queryIntent(intent, resolvedType,
7489                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7490         }
7491 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)7492         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7493                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
7494             if (!sUserManager.exists(userId)) return null;
7495             if (packageServices == null) {
7496                 return null;
7497             }
7498             mFlags = flags;
7499             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7500             final int N = packageServices.size();
7501             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
7502                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
7503 
7504             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
7505             for (int i = 0; i < N; ++i) {
7506                 intentFilters = packageServices.get(i).intents;
7507                 if (intentFilters != null && intentFilters.size() > 0) {
7508                     PackageParser.ServiceIntentInfo[] array =
7509                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
7510                     intentFilters.toArray(array);
7511                     listCut.add(array);
7512                 }
7513             }
7514             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7515         }
7516 
addService(PackageParser.Service s)7517         public final void addService(PackageParser.Service s) {
7518             mServices.put(s.getComponentName(), s);
7519             if (DEBUG_SHOW_INFO) {
7520                 Log.v(TAG, "  "
7521                         + (s.info.nonLocalizedLabel != null
7522                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
7523                 Log.v(TAG, "    Class=" + s.info.name);
7524             }
7525             final int NI = s.intents.size();
7526             int j;
7527             for (j=0; j<NI; j++) {
7528                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7529                 if (DEBUG_SHOW_INFO) {
7530                     Log.v(TAG, "    IntentFilter:");
7531                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7532                 }
7533                 if (!intent.debugCheck()) {
7534                     Log.w(TAG, "==> For Service " + s.info.name);
7535                 }
7536                 addFilter(intent);
7537             }
7538         }
7539 
removeService(PackageParser.Service s)7540         public final void removeService(PackageParser.Service s) {
7541             mServices.remove(s.getComponentName());
7542             if (DEBUG_SHOW_INFO) {
7543                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
7544                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
7545                 Log.v(TAG, "    Class=" + s.info.name);
7546             }
7547             final int NI = s.intents.size();
7548             int j;
7549             for (j=0; j<NI; j++) {
7550                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7551                 if (DEBUG_SHOW_INFO) {
7552                     Log.v(TAG, "    IntentFilter:");
7553                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7554                 }
7555                 removeFilter(intent);
7556             }
7557         }
7558 
7559         @Override
allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)7560         protected boolean allowFilterResult(
7561                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
7562             ServiceInfo filterSi = filter.service.info;
7563             for (int i=dest.size()-1; i>=0; i--) {
7564                 ServiceInfo destAi = dest.get(i).serviceInfo;
7565                 if (destAi.name == filterSi.name
7566                         && destAi.packageName == filterSi.packageName) {
7567                     return false;
7568                 }
7569             }
7570             return true;
7571         }
7572 
7573         @Override
newArray(int size)7574         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
7575             return new PackageParser.ServiceIntentInfo[size];
7576         }
7577 
7578         @Override
isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)7579         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
7580             if (!sUserManager.exists(userId)) return true;
7581             PackageParser.Package p = filter.service.owner;
7582             if (p != null) {
7583                 PackageSetting ps = (PackageSetting)p.mExtras;
7584                 if (ps != null) {
7585                     // System apps are never considered stopped for purposes of
7586                     // filtering, because there may be no way for the user to
7587                     // actually re-launch them.
7588                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7589                             && ps.getStopped(userId);
7590                 }
7591             }
7592             return false;
7593         }
7594 
7595         @Override
isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)7596         protected boolean isPackageForFilter(String packageName,
7597                 PackageParser.ServiceIntentInfo info) {
7598             return packageName.equals(info.service.owner.packageName);
7599         }
7600 
7601         @Override
newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)7602         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
7603                 int match, int userId) {
7604             if (!sUserManager.exists(userId)) return null;
7605             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
7606             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
7607                 return null;
7608             }
7609             final PackageParser.Service service = info.service;
7610             if (mSafeMode && (service.info.applicationInfo.flags
7611                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
7612                 return null;
7613             }
7614             PackageSetting ps = (PackageSetting) service.owner.mExtras;
7615             if (ps == null) {
7616                 return null;
7617             }
7618             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
7619                     ps.readUserState(userId), userId);
7620             if (si == null) {
7621                 return null;
7622             }
7623             final ResolveInfo res = new ResolveInfo();
7624             res.serviceInfo = si;
7625             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7626                 res.filter = filter;
7627             }
7628             res.priority = info.getPriority();
7629             res.preferredOrder = service.owner.mPreferredOrder;
7630             //System.out.println("Result: " + res.activityInfo.className +
7631             //                   " = " + res.priority);
7632             res.match = match;
7633             res.isDefault = info.hasDefault;
7634             res.labelRes = info.labelRes;
7635             res.nonLocalizedLabel = info.nonLocalizedLabel;
7636             res.icon = info.icon;
7637             res.system = isSystemApp(res.serviceInfo.applicationInfo);
7638             return res;
7639         }
7640 
7641         @Override
sortResults(List<ResolveInfo> results)7642         protected void sortResults(List<ResolveInfo> results) {
7643             Collections.sort(results, mResolvePrioritySorter);
7644         }
7645 
7646         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)7647         protected void dumpFilter(PrintWriter out, String prefix,
7648                 PackageParser.ServiceIntentInfo filter) {
7649             out.print(prefix); out.print(
7650                     Integer.toHexString(System.identityHashCode(filter.service)));
7651                     out.print(' ');
7652                     filter.service.printComponentShortName(out);
7653                     out.print(" filter ");
7654                     out.println(Integer.toHexString(System.identityHashCode(filter)));
7655         }
7656 
7657         @Override
filterToLabel(PackageParser.ServiceIntentInfo filter)7658         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
7659             return filter.service;
7660         }
7661 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)7662         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
7663             PackageParser.Service service = (PackageParser.Service)label;
7664             out.print(prefix); out.print(
7665                     Integer.toHexString(System.identityHashCode(service)));
7666                     out.print(' ');
7667                     service.printComponentShortName(out);
7668             if (count > 1) {
7669                 out.print(" ("); out.print(count); out.print(" filters)");
7670             }
7671             out.println();
7672         }
7673 
7674 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7675 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7676 //            final List<ResolveInfo> retList = Lists.newArrayList();
7677 //            while (i.hasNext()) {
7678 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
7679 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
7680 //                    retList.add(resolveInfo);
7681 //                }
7682 //            }
7683 //            return retList;
7684 //        }
7685 
7686         // Keys are String (activity class name), values are Activity.
7687         private final ArrayMap<ComponentName, PackageParser.Service> mServices
7688                 = new ArrayMap<ComponentName, PackageParser.Service>();
7689         private int mFlags;
7690     };
7691 
7692     private final class ProviderIntentResolver
7693             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)7694         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7695                 boolean defaultOnly, int userId) {
7696             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7697             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7698         }
7699 
queryIntent(Intent intent, String resolvedType, int flags, int userId)7700         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7701                 int userId) {
7702             if (!sUserManager.exists(userId))
7703                 return null;
7704             mFlags = flags;
7705             return super.queryIntent(intent, resolvedType,
7706                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7707         }
7708 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)7709         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7710                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
7711             if (!sUserManager.exists(userId))
7712                 return null;
7713             if (packageProviders == null) {
7714                 return null;
7715             }
7716             mFlags = flags;
7717             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
7718             final int N = packageProviders.size();
7719             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
7720                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
7721 
7722             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
7723             for (int i = 0; i < N; ++i) {
7724                 intentFilters = packageProviders.get(i).intents;
7725                 if (intentFilters != null && intentFilters.size() > 0) {
7726                     PackageParser.ProviderIntentInfo[] array =
7727                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
7728                     intentFilters.toArray(array);
7729                     listCut.add(array);
7730                 }
7731             }
7732             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7733         }
7734 
addProvider(PackageParser.Provider p)7735         public final void addProvider(PackageParser.Provider p) {
7736             if (mProviders.containsKey(p.getComponentName())) {
7737                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
7738                 return;
7739             }
7740 
7741             mProviders.put(p.getComponentName(), p);
7742             if (DEBUG_SHOW_INFO) {
7743                 Log.v(TAG, "  "
7744                         + (p.info.nonLocalizedLabel != null
7745                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
7746                 Log.v(TAG, "    Class=" + p.info.name);
7747             }
7748             final int NI = p.intents.size();
7749             int j;
7750             for (j = 0; j < NI; j++) {
7751                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7752                 if (DEBUG_SHOW_INFO) {
7753                     Log.v(TAG, "    IntentFilter:");
7754                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7755                 }
7756                 if (!intent.debugCheck()) {
7757                     Log.w(TAG, "==> For Provider " + p.info.name);
7758                 }
7759                 addFilter(intent);
7760             }
7761         }
7762 
removeProvider(PackageParser.Provider p)7763         public final void removeProvider(PackageParser.Provider p) {
7764             mProviders.remove(p.getComponentName());
7765             if (DEBUG_SHOW_INFO) {
7766                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
7767                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
7768                 Log.v(TAG, "    Class=" + p.info.name);
7769             }
7770             final int NI = p.intents.size();
7771             int j;
7772             for (j = 0; j < NI; j++) {
7773                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7774                 if (DEBUG_SHOW_INFO) {
7775                     Log.v(TAG, "    IntentFilter:");
7776                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7777                 }
7778                 removeFilter(intent);
7779             }
7780         }
7781 
7782         @Override
allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)7783         protected boolean allowFilterResult(
7784                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
7785             ProviderInfo filterPi = filter.provider.info;
7786             for (int i = dest.size() - 1; i >= 0; i--) {
7787                 ProviderInfo destPi = dest.get(i).providerInfo;
7788                 if (destPi.name == filterPi.name
7789                         && destPi.packageName == filterPi.packageName) {
7790                     return false;
7791                 }
7792             }
7793             return true;
7794         }
7795 
7796         @Override
newArray(int size)7797         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
7798             return new PackageParser.ProviderIntentInfo[size];
7799         }
7800 
7801         @Override
isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)7802         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
7803             if (!sUserManager.exists(userId))
7804                 return true;
7805             PackageParser.Package p = filter.provider.owner;
7806             if (p != null) {
7807                 PackageSetting ps = (PackageSetting) p.mExtras;
7808                 if (ps != null) {
7809                     // System apps are never considered stopped for purposes of
7810                     // filtering, because there may be no way for the user to
7811                     // actually re-launch them.
7812                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7813                             && ps.getStopped(userId);
7814                 }
7815             }
7816             return false;
7817         }
7818 
7819         @Override
isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)7820         protected boolean isPackageForFilter(String packageName,
7821                 PackageParser.ProviderIntentInfo info) {
7822             return packageName.equals(info.provider.owner.packageName);
7823         }
7824 
7825         @Override
newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)7826         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
7827                 int match, int userId) {
7828             if (!sUserManager.exists(userId))
7829                 return null;
7830             final PackageParser.ProviderIntentInfo info = filter;
7831             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
7832                 return null;
7833             }
7834             final PackageParser.Provider provider = info.provider;
7835             if (mSafeMode && (provider.info.applicationInfo.flags
7836                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
7837                 return null;
7838             }
7839             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
7840             if (ps == null) {
7841                 return null;
7842             }
7843             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
7844                     ps.readUserState(userId), userId);
7845             if (pi == null) {
7846                 return null;
7847             }
7848             final ResolveInfo res = new ResolveInfo();
7849             res.providerInfo = pi;
7850             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
7851                 res.filter = filter;
7852             }
7853             res.priority = info.getPriority();
7854             res.preferredOrder = provider.owner.mPreferredOrder;
7855             res.match = match;
7856             res.isDefault = info.hasDefault;
7857             res.labelRes = info.labelRes;
7858             res.nonLocalizedLabel = info.nonLocalizedLabel;
7859             res.icon = info.icon;
7860             res.system = isSystemApp(res.providerInfo.applicationInfo);
7861             return res;
7862         }
7863 
7864         @Override
sortResults(List<ResolveInfo> results)7865         protected void sortResults(List<ResolveInfo> results) {
7866             Collections.sort(results, mResolvePrioritySorter);
7867         }
7868 
7869         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)7870         protected void dumpFilter(PrintWriter out, String prefix,
7871                 PackageParser.ProviderIntentInfo filter) {
7872             out.print(prefix);
7873             out.print(
7874                     Integer.toHexString(System.identityHashCode(filter.provider)));
7875             out.print(' ');
7876             filter.provider.printComponentShortName(out);
7877             out.print(" filter ");
7878             out.println(Integer.toHexString(System.identityHashCode(filter)));
7879         }
7880 
7881         @Override
filterToLabel(PackageParser.ProviderIntentInfo filter)7882         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
7883             return filter.provider;
7884         }
7885 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)7886         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
7887             PackageParser.Provider provider = (PackageParser.Provider)label;
7888             out.print(prefix); out.print(
7889                     Integer.toHexString(System.identityHashCode(provider)));
7890                     out.print(' ');
7891                     provider.printComponentShortName(out);
7892             if (count > 1) {
7893                 out.print(" ("); out.print(count); out.print(" filters)");
7894             }
7895             out.println();
7896         }
7897 
7898         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
7899                 = new ArrayMap<ComponentName, PackageParser.Provider>();
7900         private int mFlags;
7901     };
7902 
7903     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
7904             new Comparator<ResolveInfo>() {
7905         public int compare(ResolveInfo r1, ResolveInfo r2) {
7906             int v1 = r1.priority;
7907             int v2 = r2.priority;
7908             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
7909             if (v1 != v2) {
7910                 return (v1 > v2) ? -1 : 1;
7911             }
7912             v1 = r1.preferredOrder;
7913             v2 = r2.preferredOrder;
7914             if (v1 != v2) {
7915                 return (v1 > v2) ? -1 : 1;
7916             }
7917             if (r1.isDefault != r2.isDefault) {
7918                 return r1.isDefault ? -1 : 1;
7919             }
7920             v1 = r1.match;
7921             v2 = r2.match;
7922             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
7923             if (v1 != v2) {
7924                 return (v1 > v2) ? -1 : 1;
7925             }
7926             if (r1.system != r2.system) {
7927                 return r1.system ? -1 : 1;
7928             }
7929             return 0;
7930         }
7931     };
7932 
7933     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
7934             new Comparator<ProviderInfo>() {
7935         public int compare(ProviderInfo p1, ProviderInfo p2) {
7936             final int v1 = p1.initOrder;
7937             final int v2 = p2.initOrder;
7938             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
7939         }
7940     };
7941 
sendPackageBroadcast(String action, String pkg, Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, int[] userIds)7942     static final void sendPackageBroadcast(String action, String pkg,
7943             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
7944             int[] userIds) {
7945         IActivityManager am = ActivityManagerNative.getDefault();
7946         if (am != null) {
7947             try {
7948                 if (userIds == null) {
7949                     userIds = am.getRunningUserIds();
7950                 }
7951                 for (int id : userIds) {
7952                     final Intent intent = new Intent(action,
7953                             pkg != null ? Uri.fromParts("package", pkg, null) : null);
7954                     if (extras != null) {
7955                         intent.putExtras(extras);
7956                     }
7957                     if (targetPkg != null) {
7958                         intent.setPackage(targetPkg);
7959                     }
7960                     // Modify the UID when posting to other users
7961                     int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
7962                     if (uid > 0 && UserHandle.getUserId(uid) != id) {
7963                         uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
7964                         intent.putExtra(Intent.EXTRA_UID, uid);
7965                     }
7966                     intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
7967                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
7968                     if (DEBUG_BROADCASTS) {
7969                         RuntimeException here = new RuntimeException("here");
7970                         here.fillInStackTrace();
7971                         Slog.d(TAG, "Sending to user " + id + ": "
7972                                 + intent.toShortString(false, true, false, false)
7973                                 + " " + intent.getExtras(), here);
7974                     }
7975                     am.broadcastIntent(null, intent, null, finishedReceiver,
7976                             0, null, null, null, android.app.AppOpsManager.OP_NONE,
7977                             finishedReceiver != null, false, id);
7978                 }
7979             } catch (RemoteException ex) {
7980             }
7981         }
7982     }
7983 
7984     /**
7985      * Check if the external storage media is available. This is true if there
7986      * is a mounted external storage medium or if the external storage is
7987      * emulated.
7988      */
isExternalMediaAvailable()7989     private boolean isExternalMediaAvailable() {
7990         return mMediaMounted || Environment.isExternalStorageEmulated();
7991     }
7992 
7993     @Override
nextPackageToClean(PackageCleanItem lastPackage)7994     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
7995         // writer
7996         synchronized (mPackages) {
7997             if (!isExternalMediaAvailable()) {
7998                 // If the external storage is no longer mounted at this point,
7999                 // the caller may not have been able to delete all of this
8000                 // packages files and can not delete any more.  Bail.
8001                 return null;
8002             }
8003             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
8004             if (lastPackage != null) {
8005                 pkgs.remove(lastPackage);
8006             }
8007             if (pkgs.size() > 0) {
8008                 return pkgs.get(0);
8009             }
8010         }
8011         return null;
8012     }
8013 
schedulePackageCleaning(String packageName, int userId, boolean andCode)8014     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
8015         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
8016                 userId, andCode ? 1 : 0, packageName);
8017         if (mSystemReady) {
8018             msg.sendToTarget();
8019         } else {
8020             if (mPostSystemReadyMessages == null) {
8021                 mPostSystemReadyMessages = new ArrayList<>();
8022             }
8023             mPostSystemReadyMessages.add(msg);
8024         }
8025     }
8026 
startCleaningPackages()8027     void startCleaningPackages() {
8028         // reader
8029         synchronized (mPackages) {
8030             if (!isExternalMediaAvailable()) {
8031                 return;
8032             }
8033             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
8034                 return;
8035             }
8036         }
8037         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
8038         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
8039         IActivityManager am = ActivityManagerNative.getDefault();
8040         if (am != null) {
8041             try {
8042                 am.startService(null, intent, null, UserHandle.USER_OWNER);
8043             } catch (RemoteException e) {
8044             }
8045         }
8046     }
8047 
8048     @Override
installPackage(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride)8049     public void installPackage(String originPath, IPackageInstallObserver2 observer,
8050             int installFlags, String installerPackageName, VerificationParams verificationParams,
8051             String packageAbiOverride) {
8052         installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
8053                 packageAbiOverride, UserHandle.getCallingUserId());
8054     }
8055 
8056     @Override
installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride, int userId)8057     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
8058             int installFlags, String installerPackageName, VerificationParams verificationParams,
8059             String packageAbiOverride, int userId) {
8060         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
8061 
8062         final int callingUid = Binder.getCallingUid();
8063         enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
8064 
8065         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8066             try {
8067                 if (observer != null) {
8068                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
8069                 }
8070             } catch (RemoteException re) {
8071             }
8072             return;
8073         }
8074 
8075         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
8076             installFlags |= PackageManager.INSTALL_FROM_ADB;
8077 
8078         } else {
8079             // Caller holds INSTALL_PACKAGES permission, so we're less strict
8080             // about installerPackageName.
8081 
8082             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
8083             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
8084         }
8085 
8086         UserHandle user;
8087         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
8088             user = UserHandle.ALL;
8089         } else {
8090             user = new UserHandle(userId);
8091         }
8092 
8093         verificationParams.setInstallerUid(callingUid);
8094 
8095         final File originFile = new File(originPath);
8096         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
8097 
8098         final Message msg = mHandler.obtainMessage(INIT_COPY);
8099         msg.obj = new InstallParams(origin, observer, installFlags,
8100                 installerPackageName, verificationParams, user, packageAbiOverride);
8101         mHandler.sendMessage(msg);
8102     }
8103 
installStage(String packageName, File stagedDir, String stagedCid, IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, String installerPackageName, int installerUid, UserHandle user)8104     void installStage(String packageName, File stagedDir, String stagedCid,
8105             IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
8106             String installerPackageName, int installerUid, UserHandle user) {
8107         final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
8108                 params.referrerUri, installerUid, null);
8109 
8110         final OriginInfo origin;
8111         if (stagedDir != null) {
8112             origin = OriginInfo.fromStagedFile(stagedDir);
8113         } else {
8114             origin = OriginInfo.fromStagedContainer(stagedCid);
8115         }
8116 
8117         final Message msg = mHandler.obtainMessage(INIT_COPY);
8118         msg.obj = new InstallParams(origin, observer, params.installFlags,
8119                 installerPackageName, verifParams, user, params.abiOverride);
8120         mHandler.sendMessage(msg);
8121     }
8122 
sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)8123     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
8124         Bundle extras = new Bundle(1);
8125         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
8126 
8127         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
8128                 packageName, extras, null, null, new int[] {userId});
8129         try {
8130             IActivityManager am = ActivityManagerNative.getDefault();
8131             final boolean isSystem =
8132                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
8133             if (isSystem && am.isUserRunning(userId, false)) {
8134                 // The just-installed/enabled app is bundled on the system, so presumed
8135                 // to be able to run automatically without needing an explicit launch.
8136                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
8137                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
8138                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
8139                         .setPackage(packageName);
8140                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
8141                         android.app.AppOpsManager.OP_NONE, false, false, userId);
8142             }
8143         } catch (RemoteException e) {
8144             // shouldn't happen
8145             Slog.w(TAG, "Unable to bootstrap installed package", e);
8146         }
8147     }
8148 
8149     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)8150     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
8151             int userId) {
8152         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8153         PackageSetting pkgSetting;
8154         final int uid = Binder.getCallingUid();
8155         enforceCrossUserPermission(uid, userId, true, true,
8156                 "setApplicationHiddenSetting for user " + userId);
8157 
8158         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
8159             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
8160             return false;
8161         }
8162 
8163         long callingId = Binder.clearCallingIdentity();
8164         try {
8165             boolean sendAdded = false;
8166             boolean sendRemoved = false;
8167             // writer
8168             synchronized (mPackages) {
8169                 pkgSetting = mSettings.mPackages.get(packageName);
8170                 if (pkgSetting == null) {
8171                     return false;
8172                 }
8173                 if (pkgSetting.getHidden(userId) != hidden) {
8174                     pkgSetting.setHidden(hidden, userId);
8175                     mSettings.writePackageRestrictionsLPr(userId);
8176                     if (hidden) {
8177                         sendRemoved = true;
8178                     } else {
8179                         sendAdded = true;
8180                     }
8181                 }
8182             }
8183             if (sendAdded) {
8184                 sendPackageAddedForUser(packageName, pkgSetting, userId);
8185                 return true;
8186             }
8187             if (sendRemoved) {
8188                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
8189                         "hiding pkg");
8190                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
8191             }
8192         } finally {
8193             Binder.restoreCallingIdentity(callingId);
8194         }
8195         return false;
8196     }
8197 
sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)8198     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
8199             int userId) {
8200         final PackageRemovedInfo info = new PackageRemovedInfo();
8201         info.removedPackage = packageName;
8202         info.removedUsers = new int[] {userId};
8203         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
8204         info.sendBroadcast(false, false, false);
8205     }
8206 
8207     /**
8208      * Returns true if application is not found or there was an error. Otherwise it returns
8209      * the hidden state of the package for the given user.
8210      */
8211     @Override
getApplicationHiddenSettingAsUser(String packageName, int userId)8212     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
8213         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8214         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
8215                 false, "getApplicationHidden for user " + userId);
8216         PackageSetting pkgSetting;
8217         long callingId = Binder.clearCallingIdentity();
8218         try {
8219             // writer
8220             synchronized (mPackages) {
8221                 pkgSetting = mSettings.mPackages.get(packageName);
8222                 if (pkgSetting == null) {
8223                     return true;
8224                 }
8225                 return pkgSetting.getHidden(userId);
8226             }
8227         } finally {
8228             Binder.restoreCallingIdentity(callingId);
8229         }
8230     }
8231 
8232     /**
8233      * @hide
8234      */
8235     @Override
installExistingPackageAsUser(String packageName, int userId)8236     public int installExistingPackageAsUser(String packageName, int userId) {
8237         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
8238                 null);
8239         PackageSetting pkgSetting;
8240         final int uid = Binder.getCallingUid();
8241         enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
8242                 + userId);
8243         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8244             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
8245         }
8246 
8247         long callingId = Binder.clearCallingIdentity();
8248         try {
8249             boolean sendAdded = false;
8250             Bundle extras = new Bundle(1);
8251 
8252             // writer
8253             synchronized (mPackages) {
8254                 pkgSetting = mSettings.mPackages.get(packageName);
8255                 if (pkgSetting == null) {
8256                     return PackageManager.INSTALL_FAILED_INVALID_URI;
8257                 }
8258                 if (!pkgSetting.getInstalled(userId)) {
8259                     pkgSetting.setInstalled(true, userId);
8260                     pkgSetting.setHidden(false, userId);
8261                     mSettings.writePackageRestrictionsLPr(userId);
8262                     sendAdded = true;
8263                 }
8264             }
8265 
8266             if (sendAdded) {
8267                 sendPackageAddedForUser(packageName, pkgSetting, userId);
8268             }
8269         } finally {
8270             Binder.restoreCallingIdentity(callingId);
8271         }
8272 
8273         return PackageManager.INSTALL_SUCCEEDED;
8274     }
8275 
isUserRestricted(int userId, String restrictionKey)8276     boolean isUserRestricted(int userId, String restrictionKey) {
8277         Bundle restrictions = sUserManager.getUserRestrictions(userId);
8278         if (restrictions.getBoolean(restrictionKey, false)) {
8279             Log.w(TAG, "User is restricted: " + restrictionKey);
8280             return true;
8281         }
8282         return false;
8283     }
8284 
8285     @Override
verifyPendingInstall(int id, int verificationCode)8286     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
8287         mContext.enforceCallingOrSelfPermission(
8288                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8289                 "Only package verification agents can verify applications");
8290 
8291         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8292         final PackageVerificationResponse response = new PackageVerificationResponse(
8293                 verificationCode, Binder.getCallingUid());
8294         msg.arg1 = id;
8295         msg.obj = response;
8296         mHandler.sendMessage(msg);
8297     }
8298 
8299     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)8300     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
8301             long millisecondsToDelay) {
8302         mContext.enforceCallingOrSelfPermission(
8303                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8304                 "Only package verification agents can extend verification timeouts");
8305 
8306         final PackageVerificationState state = mPendingVerification.get(id);
8307         final PackageVerificationResponse response = new PackageVerificationResponse(
8308                 verificationCodeAtTimeout, Binder.getCallingUid());
8309 
8310         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
8311             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
8312         }
8313         if (millisecondsToDelay < 0) {
8314             millisecondsToDelay = 0;
8315         }
8316         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
8317                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
8318             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
8319         }
8320 
8321         if ((state != null) && !state.timeoutExtended()) {
8322             state.extendTimeout();
8323 
8324             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8325             msg.arg1 = id;
8326             msg.obj = response;
8327             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
8328         }
8329     }
8330 
broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)8331     private void broadcastPackageVerified(int verificationId, Uri packageUri,
8332             int verificationCode, UserHandle user) {
8333         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
8334         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
8335         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8336         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8337         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
8338 
8339         mContext.sendBroadcastAsUser(intent, user,
8340                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
8341     }
8342 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)8343     private ComponentName matchComponentForVerifier(String packageName,
8344             List<ResolveInfo> receivers) {
8345         ActivityInfo targetReceiver = null;
8346 
8347         final int NR = receivers.size();
8348         for (int i = 0; i < NR; i++) {
8349             final ResolveInfo info = receivers.get(i);
8350             if (info.activityInfo == null) {
8351                 continue;
8352             }
8353 
8354             if (packageName.equals(info.activityInfo.packageName)) {
8355                 targetReceiver = info.activityInfo;
8356                 break;
8357             }
8358         }
8359 
8360         if (targetReceiver == null) {
8361             return null;
8362         }
8363 
8364         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
8365     }
8366 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)8367     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
8368             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
8369         if (pkgInfo.verifiers.length == 0) {
8370             return null;
8371         }
8372 
8373         final int N = pkgInfo.verifiers.length;
8374         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
8375         for (int i = 0; i < N; i++) {
8376             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
8377 
8378             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
8379                     receivers);
8380             if (comp == null) {
8381                 continue;
8382             }
8383 
8384             final int verifierUid = getUidForVerifier(verifierInfo);
8385             if (verifierUid == -1) {
8386                 continue;
8387             }
8388 
8389             if (DEBUG_VERIFY) {
8390                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
8391                         + " with the correct signature");
8392             }
8393             sufficientVerifiers.add(comp);
8394             verificationState.addSufficientVerifier(verifierUid);
8395         }
8396 
8397         return sufficientVerifiers;
8398     }
8399 
getUidForVerifier(VerifierInfo verifierInfo)8400     private int getUidForVerifier(VerifierInfo verifierInfo) {
8401         synchronized (mPackages) {
8402             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
8403             if (pkg == null) {
8404                 return -1;
8405             } else if (pkg.mSignatures.length != 1) {
8406                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8407                         + " has more than one signature; ignoring");
8408                 return -1;
8409             }
8410 
8411             /*
8412              * If the public key of the package's signature does not match
8413              * our expected public key, then this is a different package and
8414              * we should skip.
8415              */
8416 
8417             final byte[] expectedPublicKey;
8418             try {
8419                 final Signature verifierSig = pkg.mSignatures[0];
8420                 final PublicKey publicKey = verifierSig.getPublicKey();
8421                 expectedPublicKey = publicKey.getEncoded();
8422             } catch (CertificateException e) {
8423                 return -1;
8424             }
8425 
8426             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
8427 
8428             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
8429                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8430                         + " does not have the expected public key; ignoring");
8431                 return -1;
8432             }
8433 
8434             return pkg.applicationInfo.uid;
8435         }
8436     }
8437 
8438     @Override
finishPackageInstall(int token)8439     public void finishPackageInstall(int token) {
8440         enforceSystemOrRoot("Only the system is allowed to finish installs");
8441 
8442         if (DEBUG_INSTALL) {
8443             Slog.v(TAG, "BM finishing package install for " + token);
8444         }
8445 
8446         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8447         mHandler.sendMessage(msg);
8448     }
8449 
8450     /**
8451      * Get the verification agent timeout.
8452      *
8453      * @return verification timeout in milliseconds
8454      */
getVerificationTimeout()8455     private long getVerificationTimeout() {
8456         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8457                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
8458                 DEFAULT_VERIFICATION_TIMEOUT);
8459     }
8460 
8461     /**
8462      * Get the default verification agent response code.
8463      *
8464      * @return default verification response code
8465      */
getDefaultVerificationResponse()8466     private int getDefaultVerificationResponse() {
8467         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8468                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
8469                 DEFAULT_VERIFICATION_RESPONSE);
8470     }
8471 
8472     /**
8473      * Check whether or not package verification has been enabled.
8474      *
8475      * @return true if verification should be performed
8476      */
isVerificationEnabled(int userId, int installFlags)8477     private boolean isVerificationEnabled(int userId, int installFlags) {
8478         if (!DEFAULT_VERIFY_ENABLE) {
8479             return false;
8480         }
8481 
8482         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
8483 
8484         // Check if installing from ADB
8485         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
8486             // Do not run verification in a test harness environment
8487             if (ActivityManager.isRunningInTestHarness()) {
8488                 return false;
8489             }
8490             if (ensureVerifyAppsEnabled) {
8491                 return true;
8492             }
8493             // Check if the developer does not want package verification for ADB installs
8494             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8495                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
8496                 return false;
8497             }
8498         }
8499 
8500         if (ensureVerifyAppsEnabled) {
8501             return true;
8502         }
8503 
8504         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8505                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
8506     }
8507 
8508     /**
8509      * Get the "allow unknown sources" setting.
8510      *
8511      * @return the current "allow unknown sources" setting
8512      */
getUnknownSourcesSettings()8513     private int getUnknownSourcesSettings() {
8514         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8515                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
8516                 -1);
8517     }
8518 
8519     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)8520     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
8521         final int uid = Binder.getCallingUid();
8522         // writer
8523         synchronized (mPackages) {
8524             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
8525             if (targetPackageSetting == null) {
8526                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
8527             }
8528 
8529             PackageSetting installerPackageSetting;
8530             if (installerPackageName != null) {
8531                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
8532                 if (installerPackageSetting == null) {
8533                     throw new IllegalArgumentException("Unknown installer package: "
8534                             + installerPackageName);
8535                 }
8536             } else {
8537                 installerPackageSetting = null;
8538             }
8539 
8540             Signature[] callerSignature;
8541             Object obj = mSettings.getUserIdLPr(uid);
8542             if (obj != null) {
8543                 if (obj instanceof SharedUserSetting) {
8544                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
8545                 } else if (obj instanceof PackageSetting) {
8546                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
8547                 } else {
8548                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
8549                 }
8550             } else {
8551                 throw new SecurityException("Unknown calling uid " + uid);
8552             }
8553 
8554             // Verify: can't set installerPackageName to a package that is
8555             // not signed with the same cert as the caller.
8556             if (installerPackageSetting != null) {
8557                 if (compareSignatures(callerSignature,
8558                         installerPackageSetting.signatures.mSignatures)
8559                         != PackageManager.SIGNATURE_MATCH) {
8560                     throw new SecurityException(
8561                             "Caller does not have same cert as new installer package "
8562                             + installerPackageName);
8563                 }
8564             }
8565 
8566             // Verify: if target already has an installer package, it must
8567             // be signed with the same cert as the caller.
8568             if (targetPackageSetting.installerPackageName != null) {
8569                 PackageSetting setting = mSettings.mPackages.get(
8570                         targetPackageSetting.installerPackageName);
8571                 // If the currently set package isn't valid, then it's always
8572                 // okay to change it.
8573                 if (setting != null) {
8574                     if (compareSignatures(callerSignature,
8575                             setting.signatures.mSignatures)
8576                             != PackageManager.SIGNATURE_MATCH) {
8577                         throw new SecurityException(
8578                                 "Caller does not have same cert as old installer package "
8579                                 + targetPackageSetting.installerPackageName);
8580                     }
8581                 }
8582             }
8583 
8584             // Okay!
8585             targetPackageSetting.installerPackageName = installerPackageName;
8586             scheduleWriteSettingsLocked();
8587         }
8588     }
8589 
processPendingInstall(final InstallArgs args, final int currentStatus)8590     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
8591         // Queue up an async operation since the package installation may take a little while.
8592         mHandler.post(new Runnable() {
8593             public void run() {
8594                 mHandler.removeCallbacks(this);
8595                  // Result object to be returned
8596                 PackageInstalledInfo res = new PackageInstalledInfo();
8597                 res.returnCode = currentStatus;
8598                 res.uid = -1;
8599                 res.pkg = null;
8600                 res.removedInfo = new PackageRemovedInfo();
8601                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
8602                     args.doPreInstall(res.returnCode);
8603                     synchronized (mInstallLock) {
8604                         installPackageLI(args, res);
8605                     }
8606                     args.doPostInstall(res.returnCode, res.uid);
8607                 }
8608 
8609                 // A restore should be performed at this point if (a) the install
8610                 // succeeded, (b) the operation is not an update, and (c) the new
8611                 // package has not opted out of backup participation.
8612                 final boolean update = res.removedInfo.removedPackage != null;
8613                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
8614                 boolean doRestore = !update
8615                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
8616 
8617                 // Set up the post-install work request bookkeeping.  This will be used
8618                 // and cleaned up by the post-install event handling regardless of whether
8619                 // there's a restore pass performed.  Token values are >= 1.
8620                 int token;
8621                 if (mNextInstallToken < 0) mNextInstallToken = 1;
8622                 token = mNextInstallToken++;
8623 
8624                 PostInstallData data = new PostInstallData(args, res);
8625                 mRunningInstalls.put(token, data);
8626                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
8627 
8628                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
8629                     // Pass responsibility to the Backup Manager.  It will perform a
8630                     // restore if appropriate, then pass responsibility back to the
8631                     // Package Manager to run the post-install observer callbacks
8632                     // and broadcasts.
8633                     IBackupManager bm = IBackupManager.Stub.asInterface(
8634                             ServiceManager.getService(Context.BACKUP_SERVICE));
8635                     if (bm != null) {
8636                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
8637                                 + " to BM for possible restore");
8638                         try {
8639                             if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
8640                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
8641                             } else {
8642                                 doRestore = false;
8643                             }
8644                         } catch (RemoteException e) {
8645                             // can't happen; the backup manager is local
8646                         } catch (Exception e) {
8647                             Slog.e(TAG, "Exception trying to enqueue restore", e);
8648                             doRestore = false;
8649                         }
8650                     } else {
8651                         Slog.e(TAG, "Backup Manager not found!");
8652                         doRestore = false;
8653                     }
8654                 }
8655 
8656                 if (!doRestore) {
8657                     // No restore possible, or the Backup Manager was mysteriously not
8658                     // available -- just fire the post-install work request directly.
8659                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
8660                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8661                     mHandler.sendMessage(msg);
8662                 }
8663             }
8664         });
8665     }
8666 
8667     private abstract class HandlerParams {
8668         private static final int MAX_RETRIES = 4;
8669 
8670         /**
8671          * Number of times startCopy() has been attempted and had a non-fatal
8672          * error.
8673          */
8674         private int mRetries = 0;
8675 
8676         /** User handle for the user requesting the information or installation. */
8677         private final UserHandle mUser;
8678 
HandlerParams(UserHandle user)8679         HandlerParams(UserHandle user) {
8680             mUser = user;
8681         }
8682 
getUser()8683         UserHandle getUser() {
8684             return mUser;
8685         }
8686 
startCopy()8687         final boolean startCopy() {
8688             boolean res;
8689             try {
8690                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
8691 
8692                 if (++mRetries > MAX_RETRIES) {
8693                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
8694                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
8695                     handleServiceError();
8696                     return false;
8697                 } else {
8698                     handleStartCopy();
8699                     res = true;
8700                 }
8701             } catch (RemoteException e) {
8702                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
8703                 mHandler.sendEmptyMessage(MCS_RECONNECT);
8704                 res = false;
8705             }
8706             handleReturnCode();
8707             return res;
8708         }
8709 
serviceError()8710         final void serviceError() {
8711             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
8712             handleServiceError();
8713             handleReturnCode();
8714         }
8715 
handleStartCopy()8716         abstract void handleStartCopy() throws RemoteException;
handleServiceError()8717         abstract void handleServiceError();
handleReturnCode()8718         abstract void handleReturnCode();
8719     }
8720 
8721     class MeasureParams extends HandlerParams {
8722         private final PackageStats mStats;
8723         private boolean mSuccess;
8724 
8725         private final IPackageStatsObserver mObserver;
8726 
MeasureParams(PackageStats stats, IPackageStatsObserver observer)8727         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
8728             super(new UserHandle(stats.userHandle));
8729             mObserver = observer;
8730             mStats = stats;
8731         }
8732 
8733         @Override
toString()8734         public String toString() {
8735             return "MeasureParams{"
8736                 + Integer.toHexString(System.identityHashCode(this))
8737                 + " " + mStats.packageName + "}";
8738         }
8739 
8740         @Override
handleStartCopy()8741         void handleStartCopy() throws RemoteException {
8742             synchronized (mInstallLock) {
8743                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
8744             }
8745 
8746             if (mSuccess) {
8747                 final boolean mounted;
8748                 if (Environment.isExternalStorageEmulated()) {
8749                     mounted = true;
8750                 } else {
8751                     final String status = Environment.getExternalStorageState();
8752                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
8753                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
8754                 }
8755 
8756                 if (mounted) {
8757                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
8758 
8759                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
8760                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
8761 
8762                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
8763                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
8764 
8765                     // Always subtract cache size, since it's a subdirectory
8766                     mStats.externalDataSize -= mStats.externalCacheSize;
8767 
8768                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
8769                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
8770 
8771                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
8772                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
8773                 }
8774             }
8775         }
8776 
8777         @Override
handleReturnCode()8778         void handleReturnCode() {
8779             if (mObserver != null) {
8780                 try {
8781                     mObserver.onGetStatsCompleted(mStats, mSuccess);
8782                 } catch (RemoteException e) {
8783                     Slog.i(TAG, "Observer no longer exists.");
8784                 }
8785             }
8786         }
8787 
8788         @Override
handleServiceError()8789         void handleServiceError() {
8790             Slog.e(TAG, "Could not measure application " + mStats.packageName
8791                             + " external storage");
8792         }
8793     }
8794 
calculateDirectorySize(IMediaContainerService mcs, File[] paths)8795     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
8796             throws RemoteException {
8797         long result = 0;
8798         for (File path : paths) {
8799             result += mcs.calculateDirectorySize(path.getAbsolutePath());
8800         }
8801         return result;
8802     }
8803 
clearDirectory(IMediaContainerService mcs, File[] paths)8804     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
8805         for (File path : paths) {
8806             try {
8807                 mcs.clearDirectory(path.getAbsolutePath());
8808             } catch (RemoteException e) {
8809             }
8810         }
8811     }
8812 
8813     static class OriginInfo {
8814         /**
8815          * Location where install is coming from, before it has been
8816          * copied/renamed into place. This could be a single monolithic APK
8817          * file, or a cluster directory. This location may be untrusted.
8818          */
8819         final File file;
8820         final String cid;
8821 
8822         /**
8823          * Flag indicating that {@link #file} or {@link #cid} has already been
8824          * staged, meaning downstream users don't need to defensively copy the
8825          * contents.
8826          */
8827         final boolean staged;
8828 
8829         /**
8830          * Flag indicating that {@link #file} or {@link #cid} is an already
8831          * installed app that is being moved.
8832          */
8833         final boolean existing;
8834 
8835         final String resolvedPath;
8836         final File resolvedFile;
8837 
fromNothing()8838         static OriginInfo fromNothing() {
8839             return new OriginInfo(null, null, false, false);
8840         }
8841 
fromUntrustedFile(File file)8842         static OriginInfo fromUntrustedFile(File file) {
8843             return new OriginInfo(file, null, false, false);
8844         }
8845 
fromExistingFile(File file)8846         static OriginInfo fromExistingFile(File file) {
8847             return new OriginInfo(file, null, false, true);
8848         }
8849 
fromStagedFile(File file)8850         static OriginInfo fromStagedFile(File file) {
8851             return new OriginInfo(file, null, true, false);
8852         }
8853 
fromStagedContainer(String cid)8854         static OriginInfo fromStagedContainer(String cid) {
8855             return new OriginInfo(null, cid, true, false);
8856         }
8857 
OriginInfo(File file, String cid, boolean staged, boolean existing)8858         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
8859             this.file = file;
8860             this.cid = cid;
8861             this.staged = staged;
8862             this.existing = existing;
8863 
8864             if (cid != null) {
8865                 resolvedPath = PackageHelper.getSdDir(cid);
8866                 resolvedFile = new File(resolvedPath);
8867             } else if (file != null) {
8868                 resolvedPath = file.getAbsolutePath();
8869                 resolvedFile = file;
8870             } else {
8871                 resolvedPath = null;
8872                 resolvedFile = null;
8873             }
8874         }
8875     }
8876 
8877     class InstallParams extends HandlerParams {
8878         final OriginInfo origin;
8879         final IPackageInstallObserver2 observer;
8880         int installFlags;
8881         final String installerPackageName;
8882         final VerificationParams verificationParams;
8883         private InstallArgs mArgs;
8884         private int mRet;
8885         final String packageAbiOverride;
8886 
InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, UserHandle user, String packageAbiOverride)8887         InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
8888                 String installerPackageName, VerificationParams verificationParams, UserHandle user,
8889                 String packageAbiOverride) {
8890             super(user);
8891             this.origin = origin;
8892             this.observer = observer;
8893             this.installFlags = installFlags;
8894             this.installerPackageName = installerPackageName;
8895             this.verificationParams = verificationParams;
8896             this.packageAbiOverride = packageAbiOverride;
8897         }
8898 
8899         @Override
toString()8900         public String toString() {
8901             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
8902                     + " file=" + origin.file + " cid=" + origin.cid + "}";
8903         }
8904 
getManifestDigest()8905         public ManifestDigest getManifestDigest() {
8906             if (verificationParams == null) {
8907                 return null;
8908             }
8909             return verificationParams.getManifestDigest();
8910         }
8911 
installLocationPolicy(PackageInfoLite pkgLite)8912         private int installLocationPolicy(PackageInfoLite pkgLite) {
8913             String packageName = pkgLite.packageName;
8914             int installLocation = pkgLite.installLocation;
8915             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8916             // reader
8917             synchronized (mPackages) {
8918                 PackageParser.Package pkg = mPackages.get(packageName);
8919                 if (pkg != null) {
8920                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
8921                         // Check for downgrading.
8922                         if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
8923                             try {
8924                                 checkDowngrade(pkg, pkgLite);
8925                             } catch (PackageManagerException e) {
8926                                 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
8927                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
8928                             }
8929                         }
8930                         // Check for updated system application.
8931                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8932                             if (onSd) {
8933                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
8934                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
8935                             }
8936                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8937                         } else {
8938                             if (onSd) {
8939                                 // Install flag overrides everything.
8940                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8941                             }
8942                             // If current upgrade specifies particular preference
8943                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
8944                                 // Application explicitly specified internal.
8945                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8946                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
8947                                 // App explictly prefers external. Let policy decide
8948                             } else {
8949                                 // Prefer previous location
8950                                 if (isExternal(pkg)) {
8951                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8952                                 }
8953                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8954                             }
8955                         }
8956                     } else {
8957                         // Invalid install. Return error code
8958                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
8959                     }
8960                 }
8961             }
8962             // All the special cases have been taken care of.
8963             // Return result based on recommended install location.
8964             if (onSd) {
8965                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8966             }
8967             return pkgLite.recommendedInstallLocation;
8968         }
8969 
8970         /*
8971          * Invoke remote method to get package information and install
8972          * location values. Override install location based on default
8973          * policy if needed and then create install arguments based
8974          * on the install location.
8975          */
handleStartCopy()8976         public void handleStartCopy() throws RemoteException {
8977             int ret = PackageManager.INSTALL_SUCCEEDED;
8978 
8979             // If we're already staged, we've firmly committed to an install location
8980             if (origin.staged) {
8981                 if (origin.file != null) {
8982                     installFlags |= PackageManager.INSTALL_INTERNAL;
8983                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8984                 } else if (origin.cid != null) {
8985                     installFlags |= PackageManager.INSTALL_EXTERNAL;
8986                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
8987                 } else {
8988                     throw new IllegalStateException("Invalid stage location");
8989                 }
8990             }
8991 
8992             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8993             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
8994 
8995             PackageInfoLite pkgLite = null;
8996 
8997             if (onInt && onSd) {
8998                 // Check if both bits are set.
8999                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
9000                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
9001             } else {
9002                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
9003                         packageAbiOverride);
9004 
9005                 /*
9006                  * If we have too little free space, try to free cache
9007                  * before giving up.
9008                  */
9009                 if (!origin.staged && pkgLite.recommendedInstallLocation
9010                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
9011                     // TODO: focus freeing disk space on the target device
9012                     final StorageManager storage = StorageManager.from(mContext);
9013                     final long lowThreshold = storage.getStorageLowBytes(
9014                             Environment.getDataDirectory());
9015 
9016                     final long sizeBytes = mContainerService.calculateInstalledSize(
9017                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
9018 
9019                     if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
9020                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
9021                                 installFlags, packageAbiOverride);
9022                     }
9023 
9024                     /*
9025                      * The cache free must have deleted the file we
9026                      * downloaded to install.
9027                      *
9028                      * TODO: fix the "freeCache" call to not delete
9029                      *       the file we care about.
9030                      */
9031                     if (pkgLite.recommendedInstallLocation
9032                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
9033                         pkgLite.recommendedInstallLocation
9034                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
9035                     }
9036                 }
9037             }
9038 
9039             if (ret == PackageManager.INSTALL_SUCCEEDED) {
9040                 int loc = pkgLite.recommendedInstallLocation;
9041                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
9042                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
9043                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
9044                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
9045                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
9046                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9047                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
9048                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
9049                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
9050                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
9051                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
9052                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
9053                 } else {
9054                     // Override with defaults if needed.
9055                     loc = installLocationPolicy(pkgLite);
9056                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
9057                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
9058                     } else if (!onSd && !onInt) {
9059                         // Override install location with flags
9060                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
9061                             // Set the flag to install on external media.
9062                             installFlags |= PackageManager.INSTALL_EXTERNAL;
9063                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
9064                         } else {
9065                             // Make sure the flag for installing on external
9066                             // media is unset
9067                             installFlags |= PackageManager.INSTALL_INTERNAL;
9068                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
9069                         }
9070                     }
9071                 }
9072             }
9073 
9074             final InstallArgs args = createInstallArgs(this);
9075             mArgs = args;
9076 
9077             if (ret == PackageManager.INSTALL_SUCCEEDED) {
9078                  /*
9079                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
9080                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
9081                  */
9082                 int userIdentifier = getUser().getIdentifier();
9083                 if (userIdentifier == UserHandle.USER_ALL
9084                         && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
9085                     userIdentifier = UserHandle.USER_OWNER;
9086                 }
9087 
9088                 /*
9089                  * Determine if we have any installed package verifiers. If we
9090                  * do, then we'll defer to them to verify the packages.
9091                  */
9092                 final int requiredUid = mRequiredVerifierPackage == null ? -1
9093                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
9094                 if (!origin.existing && requiredUid != -1
9095                         && isVerificationEnabled(userIdentifier, installFlags)) {
9096                     final Intent verification = new Intent(
9097                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
9098                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9099                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
9100                             PACKAGE_MIME_TYPE);
9101                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
9102 
9103                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
9104                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
9105                             0 /* TODO: Which userId? */);
9106 
9107                     if (DEBUG_VERIFY) {
9108                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
9109                                 + verification.toString() + " with " + pkgLite.verifiers.length
9110                                 + " optional verifiers");
9111                     }
9112 
9113                     final int verificationId = mPendingVerificationToken++;
9114 
9115                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
9116 
9117                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
9118                             installerPackageName);
9119 
9120                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
9121                             installFlags);
9122 
9123                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
9124                             pkgLite.packageName);
9125 
9126                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
9127                             pkgLite.versionCode);
9128 
9129                     if (verificationParams != null) {
9130                         if (verificationParams.getVerificationURI() != null) {
9131                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
9132                                  verificationParams.getVerificationURI());
9133                         }
9134                         if (verificationParams.getOriginatingURI() != null) {
9135                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
9136                                   verificationParams.getOriginatingURI());
9137                         }
9138                         if (verificationParams.getReferrer() != null) {
9139                             verification.putExtra(Intent.EXTRA_REFERRER,
9140                                   verificationParams.getReferrer());
9141                         }
9142                         if (verificationParams.getOriginatingUid() >= 0) {
9143                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
9144                                   verificationParams.getOriginatingUid());
9145                         }
9146                         if (verificationParams.getInstallerUid() >= 0) {
9147                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
9148                                   verificationParams.getInstallerUid());
9149                         }
9150                     }
9151 
9152                     final PackageVerificationState verificationState = new PackageVerificationState(
9153                             requiredUid, args);
9154 
9155                     mPendingVerification.append(verificationId, verificationState);
9156 
9157                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
9158                             receivers, verificationState);
9159 
9160                     /*
9161                      * If any sufficient verifiers were listed in the package
9162                      * manifest, attempt to ask them.
9163                      */
9164                     if (sufficientVerifiers != null) {
9165                         final int N = sufficientVerifiers.size();
9166                         if (N == 0) {
9167                             Slog.i(TAG, "Additional verifiers required, but none installed.");
9168                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
9169                         } else {
9170                             for (int i = 0; i < N; i++) {
9171                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
9172 
9173                                 final Intent sufficientIntent = new Intent(verification);
9174                                 sufficientIntent.setComponent(verifierComponent);
9175 
9176                                 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
9177                             }
9178                         }
9179                     }
9180 
9181                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
9182                             mRequiredVerifierPackage, receivers);
9183                     if (ret == PackageManager.INSTALL_SUCCEEDED
9184                             && mRequiredVerifierPackage != null) {
9185                         /*
9186                          * Send the intent to the required verification agent,
9187                          * but only start the verification timeout after the
9188                          * target BroadcastReceivers have run.
9189                          */
9190                         verification.setComponent(requiredVerifierComponent);
9191                         mContext.sendOrderedBroadcastAsUser(verification, getUser(),
9192                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9193                                 new BroadcastReceiver() {
9194                                     @Override
9195                                     public void onReceive(Context context, Intent intent) {
9196                                         final Message msg = mHandler
9197                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
9198                                         msg.arg1 = verificationId;
9199                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
9200                                     }
9201                                 }, null, 0, null, null);
9202 
9203                         /*
9204                          * We don't want the copy to proceed until verification
9205                          * succeeds, so null out this field.
9206                          */
9207                         mArgs = null;
9208                     }
9209                 } else {
9210                     /*
9211                      * No package verification is enabled, so immediately start
9212                      * the remote call to initiate copy using temporary file.
9213                      */
9214                     ret = args.copyApk(mContainerService, true);
9215                 }
9216             }
9217 
9218             mRet = ret;
9219         }
9220 
9221         @Override
handleReturnCode()9222         void handleReturnCode() {
9223             // If mArgs is null, then MCS couldn't be reached. When it
9224             // reconnects, it will try again to install. At that point, this
9225             // will succeed.
9226             if (mArgs != null) {
9227                 processPendingInstall(mArgs, mRet);
9228             }
9229         }
9230 
9231         @Override
handleServiceError()9232         void handleServiceError() {
9233             mArgs = createInstallArgs(this);
9234             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9235         }
9236 
isForwardLocked()9237         public boolean isForwardLocked() {
9238             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9239         }
9240     }
9241 
9242     /**
9243      * Used during creation of InstallArgs
9244      *
9245      * @param installFlags package installation flags
9246      * @return true if should be installed on external storage
9247      */
installOnSd(int installFlags)9248     private static boolean installOnSd(int installFlags) {
9249         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
9250             return false;
9251         }
9252         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
9253             return true;
9254         }
9255         return false;
9256     }
9257 
9258     /**
9259      * Used during creation of InstallArgs
9260      *
9261      * @param installFlags package installation flags
9262      * @return true if should be installed as forward locked
9263      */
installForwardLocked(int installFlags)9264     private static boolean installForwardLocked(int installFlags) {
9265         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9266     }
9267 
createInstallArgs(InstallParams params)9268     private InstallArgs createInstallArgs(InstallParams params) {
9269         if (installOnSd(params.installFlags) || params.isForwardLocked()) {
9270             return new AsecInstallArgs(params);
9271         } else {
9272             return new FileInstallArgs(params);
9273         }
9274     }
9275 
9276     /**
9277      * Create args that describe an existing installed package. Typically used
9278      * when cleaning up old installs, or used as a move source.
9279      */
createInstallArgsForExisting(int installFlags, String codePath, String resourcePath, String nativeLibraryRoot, String[] instructionSets)9280     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
9281             String resourcePath, String nativeLibraryRoot, String[] instructionSets) {
9282         final boolean isInAsec;
9283         if (installOnSd(installFlags)) {
9284             /* Apps on SD card are always in ASEC containers. */
9285             isInAsec = true;
9286         } else if (installForwardLocked(installFlags)
9287                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
9288             /*
9289              * Forward-locked apps are only in ASEC containers if they're the
9290              * new style
9291              */
9292             isInAsec = true;
9293         } else {
9294             isInAsec = false;
9295         }
9296 
9297         if (isInAsec) {
9298             return new AsecInstallArgs(codePath, instructionSets,
9299                     installOnSd(installFlags), installForwardLocked(installFlags));
9300         } else {
9301             return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
9302                     instructionSets);
9303         }
9304     }
9305 
9306     static abstract class InstallArgs {
9307         /** @see InstallParams#origin */
9308         final OriginInfo origin;
9309 
9310         final IPackageInstallObserver2 observer;
9311         // Always refers to PackageManager flags only
9312         final int installFlags;
9313         final String installerPackageName;
9314         final ManifestDigest manifestDigest;
9315         final UserHandle user;
9316         final String abiOverride;
9317 
9318         // The list of instruction sets supported by this app. This is currently
9319         // only used during the rmdex() phase to clean up resources. We can get rid of this
9320         // if we move dex files under the common app path.
9321         /* nullable */ String[] instructionSets;
9322 
InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, String abiOverride)9323         InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
9324                 String installerPackageName, ManifestDigest manifestDigest, UserHandle user,
9325                 String[] instructionSets, String abiOverride) {
9326             this.origin = origin;
9327             this.installFlags = installFlags;
9328             this.observer = observer;
9329             this.installerPackageName = installerPackageName;
9330             this.manifestDigest = manifestDigest;
9331             this.user = user;
9332             this.instructionSets = instructionSets;
9333             this.abiOverride = abiOverride;
9334         }
9335 
copyApk(IMediaContainerService imcs, boolean temp)9336         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
doPreInstall(int status)9337         abstract int doPreInstall(int status);
9338 
9339         /**
9340          * Rename package into final resting place. All paths on the given
9341          * scanned package should be updated to reflect the rename.
9342          */
doRename(int status, PackageParser.Package pkg, String oldCodePath)9343         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
doPostInstall(int status, int uid)9344         abstract int doPostInstall(int status, int uid);
9345 
9346         /** @see PackageSettingBase#codePathString */
getCodePath()9347         abstract String getCodePath();
9348         /** @see PackageSettingBase#resourcePathString */
getResourcePath()9349         abstract String getResourcePath();
getLegacyNativeLibraryPath()9350         abstract String getLegacyNativeLibraryPath();
9351 
9352         // Need installer lock especially for dex file removal.
cleanUpResourcesLI()9353         abstract void cleanUpResourcesLI();
doPostDeleteLI(boolean delete)9354         abstract boolean doPostDeleteLI(boolean delete);
checkFreeStorage(IMediaContainerService imcs)9355         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
9356 
9357         /**
9358          * Called before the source arguments are copied. This is used mostly
9359          * for MoveParams when it needs to read the source file to put it in the
9360          * destination.
9361          */
doPreCopy()9362         int doPreCopy() {
9363             return PackageManager.INSTALL_SUCCEEDED;
9364         }
9365 
9366         /**
9367          * Called after the source arguments are copied. This is used mostly for
9368          * MoveParams when it needs to read the source file to put it in the
9369          * destination.
9370          *
9371          * @return
9372          */
doPostCopy(int uid)9373         int doPostCopy(int uid) {
9374             return PackageManager.INSTALL_SUCCEEDED;
9375         }
9376 
isFwdLocked()9377         protected boolean isFwdLocked() {
9378             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9379         }
9380 
isExternal()9381         protected boolean isExternal() {
9382             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
9383         }
9384 
getUser()9385         UserHandle getUser() {
9386             return user;
9387         }
9388     }
9389 
9390     /**
9391      * Logic to handle installation of non-ASEC applications, including copying
9392      * and renaming logic.
9393      */
9394     class FileInstallArgs extends InstallArgs {
9395         private File codeFile;
9396         private File resourceFile;
9397         private File legacyNativeLibraryPath;
9398 
9399         // Example topology:
9400         // /data/app/com.example/base.apk
9401         // /data/app/com.example/split_foo.apk
9402         // /data/app/com.example/lib/arm/libfoo.so
9403         // /data/app/com.example/lib/arm64/libfoo.so
9404         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
9405 
9406         /** New install */
FileInstallArgs(InstallParams params)9407         FileInstallArgs(InstallParams params) {
9408             super(params.origin, params.observer, params.installFlags,
9409                     params.installerPackageName, params.getManifestDigest(), params.getUser(),
9410                     null /* instruction sets */, params.packageAbiOverride);
9411             if (isFwdLocked()) {
9412                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
9413             }
9414         }
9415 
9416         /** Existing install */
FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath, String[] instructionSets)9417         FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath,
9418                 String[] instructionSets) {
9419             super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null);
9420             this.codeFile = (codePath != null) ? new File(codePath) : null;
9421             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
9422             this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ?
9423                     new File(legacyNativeLibraryPath) : null;
9424         }
9425 
checkFreeStorage(IMediaContainerService imcs)9426         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9427             final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(),
9428                     isFwdLocked(), abiOverride);
9429 
9430             final StorageManager storage = StorageManager.from(mContext);
9431             return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
9432         }
9433 
copyApk(IMediaContainerService imcs, boolean temp)9434         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9435             if (origin.staged) {
9436                 Slog.d(TAG, origin.file + " already staged; skipping copy");
9437                 codeFile = origin.file;
9438                 resourceFile = origin.file;
9439                 return PackageManager.INSTALL_SUCCEEDED;
9440             }
9441 
9442             try {
9443                 final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
9444                 codeFile = tempDir;
9445                 resourceFile = tempDir;
9446             } catch (IOException e) {
9447                 Slog.w(TAG, "Failed to create copy file: " + e);
9448                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9449             }
9450 
9451             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
9452                 @Override
9453                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
9454                     if (!FileUtils.isValidExtFilename(name)) {
9455                         throw new IllegalArgumentException("Invalid filename: " + name);
9456                     }
9457                     try {
9458                         final File file = new File(codeFile, name);
9459                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
9460                                 O_RDWR | O_CREAT, 0644);
9461                         Os.chmod(file.getAbsolutePath(), 0644);
9462                         return new ParcelFileDescriptor(fd);
9463                     } catch (ErrnoException e) {
9464                         throw new RemoteException("Failed to open: " + e.getMessage());
9465                     }
9466                 }
9467             };
9468 
9469             int ret = PackageManager.INSTALL_SUCCEEDED;
9470             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
9471             if (ret != PackageManager.INSTALL_SUCCEEDED) {
9472                 Slog.e(TAG, "Failed to copy package");
9473                 return ret;
9474             }
9475 
9476             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
9477             NativeLibraryHelper.Handle handle = null;
9478             try {
9479                 handle = NativeLibraryHelper.Handle.create(codeFile);
9480                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
9481                         abiOverride);
9482             } catch (IOException e) {
9483                 Slog.e(TAG, "Copying native libraries failed", e);
9484                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9485             } finally {
9486                 IoUtils.closeQuietly(handle);
9487             }
9488 
9489             return ret;
9490         }
9491 
doPreInstall(int status)9492         int doPreInstall(int status) {
9493             if (status != PackageManager.INSTALL_SUCCEEDED) {
9494                 cleanUp();
9495             }
9496             return status;
9497         }
9498 
doRename(int status, PackageParser.Package pkg, String oldCodePath)9499         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9500             if (status != PackageManager.INSTALL_SUCCEEDED) {
9501                 cleanUp();
9502                 return false;
9503             } else {
9504                 final File beforeCodeFile = codeFile;
9505                 final File afterCodeFile = getNextCodePath(pkg.packageName);
9506 
9507                 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
9508                 try {
9509                     Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
9510                 } catch (ErrnoException e) {
9511                     Slog.d(TAG, "Failed to rename", e);
9512                     return false;
9513                 }
9514 
9515                 if (!SELinux.restoreconRecursive(afterCodeFile)) {
9516                     Slog.d(TAG, "Failed to restorecon");
9517                     return false;
9518                 }
9519 
9520                 // Reflect the rename internally
9521                 codeFile = afterCodeFile;
9522                 resourceFile = afterCodeFile;
9523 
9524                 // Reflect the rename in scanned details
9525                 pkg.codePath = afterCodeFile.getAbsolutePath();
9526                 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9527                         pkg.baseCodePath);
9528                 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9529                         pkg.splitCodePaths);
9530 
9531                 // Reflect the rename in app info
9532                 pkg.applicationInfo.setCodePath(pkg.codePath);
9533                 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9534                 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9535                 pkg.applicationInfo.setResourcePath(pkg.codePath);
9536                 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9537                 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9538 
9539                 return true;
9540             }
9541         }
9542 
doPostInstall(int status, int uid)9543         int doPostInstall(int status, int uid) {
9544             if (status != PackageManager.INSTALL_SUCCEEDED) {
9545                 cleanUp();
9546             }
9547             return status;
9548         }
9549 
9550         @Override
getCodePath()9551         String getCodePath() {
9552             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
9553         }
9554 
9555         @Override
getResourcePath()9556         String getResourcePath() {
9557             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
9558         }
9559 
9560         @Override
getLegacyNativeLibraryPath()9561         String getLegacyNativeLibraryPath() {
9562             return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null;
9563         }
9564 
cleanUp()9565         private boolean cleanUp() {
9566             if (codeFile == null || !codeFile.exists()) {
9567                 return false;
9568             }
9569 
9570             if (codeFile.isDirectory()) {
9571                 FileUtils.deleteContents(codeFile);
9572             }
9573             codeFile.delete();
9574 
9575             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
9576                 resourceFile.delete();
9577             }
9578 
9579             if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) {
9580                 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) {
9581                     Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath);
9582                 }
9583                 legacyNativeLibraryPath.delete();
9584             }
9585 
9586             return true;
9587         }
9588 
cleanUpResourcesLI()9589         void cleanUpResourcesLI() {
9590             // Try enumerating all code paths before deleting
9591             List<String> allCodePaths = Collections.EMPTY_LIST;
9592             if (codeFile != null && codeFile.exists()) {
9593                 try {
9594                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9595                     allCodePaths = pkg.getAllCodePaths();
9596                 } catch (PackageParserException e) {
9597                     // Ignored; we tried our best
9598                 }
9599             }
9600 
9601             cleanUp();
9602 
9603             if (!allCodePaths.isEmpty()) {
9604                 if (instructionSets == null) {
9605                     throw new IllegalStateException("instructionSet == null");
9606                 }
9607                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9608                 for (String codePath : allCodePaths) {
9609                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9610                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9611                         if (retCode < 0) {
9612                             Slog.w(TAG, "Couldn't remove dex file for package: "
9613                                     + " at location " + codePath + ", retcode=" + retCode);
9614                             // we don't consider this to be a failure of the core package deletion
9615                         }
9616                     }
9617                 }
9618             }
9619         }
9620 
doPostDeleteLI(boolean delete)9621         boolean doPostDeleteLI(boolean delete) {
9622             // XXX err, shouldn't we respect the delete flag?
9623             cleanUpResourcesLI();
9624             return true;
9625         }
9626     }
9627 
isAsecExternal(String cid)9628     private boolean isAsecExternal(String cid) {
9629         final String asecPath = PackageHelper.getSdFilesystem(cid);
9630         return !asecPath.startsWith(mAsecInternalPath);
9631     }
9632 
maybeThrowExceptionForMultiArchCopy(String message, int copyRet)9633     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
9634             PackageManagerException {
9635         if (copyRet < 0) {
9636             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
9637                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
9638                 throw new PackageManagerException(copyRet, message);
9639             }
9640         }
9641     }
9642 
9643     /**
9644      * Extract the MountService "container ID" from the full code path of an
9645      * .apk.
9646      */
cidFromCodePath(String fullCodePath)9647     static String cidFromCodePath(String fullCodePath) {
9648         int eidx = fullCodePath.lastIndexOf("/");
9649         String subStr1 = fullCodePath.substring(0, eidx);
9650         int sidx = subStr1.lastIndexOf("/");
9651         return subStr1.substring(sidx+1, eidx);
9652     }
9653 
9654     /**
9655      * Logic to handle installation of ASEC applications, including copying and
9656      * renaming logic.
9657      */
9658     class AsecInstallArgs extends InstallArgs {
9659         static final String RES_FILE_NAME = "pkg.apk";
9660         static final String PUBLIC_RES_FILE_NAME = "res.zip";
9661 
9662         String cid;
9663         String packagePath;
9664         String resourcePath;
9665         String legacyNativeLibraryDir;
9666 
9667         /** New install */
AsecInstallArgs(InstallParams params)9668         AsecInstallArgs(InstallParams params) {
9669             super(params.origin, params.observer, params.installFlags,
9670                     params.installerPackageName, params.getManifestDigest(),
9671                     params.getUser(), null /* instruction sets */,
9672                     params.packageAbiOverride);
9673         }
9674 
9675         /** Existing install */
AsecInstallArgs(String fullCodePath, String[] instructionSets, boolean isExternal, boolean isForwardLocked)9676         AsecInstallArgs(String fullCodePath, String[] instructionSets,
9677                         boolean isExternal, boolean isForwardLocked) {
9678             super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0)
9679                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9680                     instructionSets, null);
9681             // Hackily pretend we're still looking at a full code path
9682             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
9683                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
9684             }
9685 
9686             // Extract cid from fullCodePath
9687             int eidx = fullCodePath.lastIndexOf("/");
9688             String subStr1 = fullCodePath.substring(0, eidx);
9689             int sidx = subStr1.lastIndexOf("/");
9690             cid = subStr1.substring(sidx+1, eidx);
9691             setMountPath(subStr1);
9692         }
9693 
AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked)9694         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
9695             super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
9696                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9697                     instructionSets, null);
9698             this.cid = cid;
9699             setMountPath(PackageHelper.getSdDir(cid));
9700         }
9701 
createCopyFile()9702         void createCopyFile() {
9703             cid = mInstallerService.allocateExternalStageCidLegacy();
9704         }
9705 
checkFreeStorage(IMediaContainerService imcs)9706         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9707             final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
9708                     abiOverride);
9709 
9710             final File target;
9711             if (isExternal()) {
9712                 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
9713             } else {
9714                 target = Environment.getDataDirectory();
9715             }
9716 
9717             final StorageManager storage = StorageManager.from(mContext);
9718             return (sizeBytes <= storage.getStorageBytesUntilLow(target));
9719         }
9720 
copyApk(IMediaContainerService imcs, boolean temp)9721         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9722             if (origin.staged) {
9723                 Slog.d(TAG, origin.cid + " already staged; skipping copy");
9724                 cid = origin.cid;
9725                 setMountPath(PackageHelper.getSdDir(cid));
9726                 return PackageManager.INSTALL_SUCCEEDED;
9727             }
9728 
9729             if (temp) {
9730                 createCopyFile();
9731             } else {
9732                 /*
9733                  * Pre-emptively destroy the container since it's destroyed if
9734                  * copying fails due to it existing anyway.
9735                  */
9736                 PackageHelper.destroySdDir(cid);
9737             }
9738 
9739             final String newMountPath = imcs.copyPackageToContainer(
9740                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
9741                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
9742 
9743             if (newMountPath != null) {
9744                 setMountPath(newMountPath);
9745                 return PackageManager.INSTALL_SUCCEEDED;
9746             } else {
9747                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9748             }
9749         }
9750 
9751         @Override
getCodePath()9752         String getCodePath() {
9753             return packagePath;
9754         }
9755 
9756         @Override
getResourcePath()9757         String getResourcePath() {
9758             return resourcePath;
9759         }
9760 
9761         @Override
getLegacyNativeLibraryPath()9762         String getLegacyNativeLibraryPath() {
9763             return legacyNativeLibraryDir;
9764         }
9765 
doPreInstall(int status)9766         int doPreInstall(int status) {
9767             if (status != PackageManager.INSTALL_SUCCEEDED) {
9768                 // Destroy container
9769                 PackageHelper.destroySdDir(cid);
9770             } else {
9771                 boolean mounted = PackageHelper.isContainerMounted(cid);
9772                 if (!mounted) {
9773                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
9774                             Process.SYSTEM_UID);
9775                     if (newMountPath != null) {
9776                         setMountPath(newMountPath);
9777                     } else {
9778                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9779                     }
9780                 }
9781             }
9782             return status;
9783         }
9784 
doRename(int status, PackageParser.Package pkg, String oldCodePath)9785         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9786             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
9787             String newMountPath = null;
9788             if (PackageHelper.isContainerMounted(cid)) {
9789                 // Unmount the container
9790                 if (!PackageHelper.unMountSdDir(cid)) {
9791                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
9792                     return false;
9793                 }
9794             }
9795             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9796                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
9797                         " which might be stale. Will try to clean up.");
9798                 // Clean up the stale container and proceed to recreate.
9799                 if (!PackageHelper.destroySdDir(newCacheId)) {
9800                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
9801                     return false;
9802                 }
9803                 // Successfully cleaned up stale container. Try to rename again.
9804                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9805                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
9806                             + " inspite of cleaning it up.");
9807                     return false;
9808                 }
9809             }
9810             if (!PackageHelper.isContainerMounted(newCacheId)) {
9811                 Slog.w(TAG, "Mounting container " + newCacheId);
9812                 newMountPath = PackageHelper.mountSdDir(newCacheId,
9813                         getEncryptKey(), Process.SYSTEM_UID);
9814             } else {
9815                 newMountPath = PackageHelper.getSdDir(newCacheId);
9816             }
9817             if (newMountPath == null) {
9818                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
9819                 return false;
9820             }
9821             Log.i(TAG, "Succesfully renamed " + cid +
9822                     " to " + newCacheId +
9823                     " at new path: " + newMountPath);
9824             cid = newCacheId;
9825 
9826             final File beforeCodeFile = new File(packagePath);
9827             setMountPath(newMountPath);
9828             final File afterCodeFile = new File(packagePath);
9829 
9830             // Reflect the rename in scanned details
9831             pkg.codePath = afterCodeFile.getAbsolutePath();
9832             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9833                     pkg.baseCodePath);
9834             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9835                     pkg.splitCodePaths);
9836 
9837             // Reflect the rename in app info
9838             pkg.applicationInfo.setCodePath(pkg.codePath);
9839             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9840             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9841             pkg.applicationInfo.setResourcePath(pkg.codePath);
9842             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9843             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9844 
9845             return true;
9846         }
9847 
setMountPath(String mountPath)9848         private void setMountPath(String mountPath) {
9849             final File mountFile = new File(mountPath);
9850 
9851             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
9852             if (monolithicFile.exists()) {
9853                 packagePath = monolithicFile.getAbsolutePath();
9854                 if (isFwdLocked()) {
9855                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
9856                 } else {
9857                     resourcePath = packagePath;
9858                 }
9859             } else {
9860                 packagePath = mountFile.getAbsolutePath();
9861                 resourcePath = packagePath;
9862             }
9863 
9864             legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
9865         }
9866 
doPostInstall(int status, int uid)9867         int doPostInstall(int status, int uid) {
9868             if (status != PackageManager.INSTALL_SUCCEEDED) {
9869                 cleanUp();
9870             } else {
9871                 final int groupOwner;
9872                 final String protectedFile;
9873                 if (isFwdLocked()) {
9874                     groupOwner = UserHandle.getSharedAppGid(uid);
9875                     protectedFile = RES_FILE_NAME;
9876                 } else {
9877                     groupOwner = -1;
9878                     protectedFile = null;
9879                 }
9880 
9881                 if (uid < Process.FIRST_APPLICATION_UID
9882                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
9883                     Slog.e(TAG, "Failed to finalize " + cid);
9884                     PackageHelper.destroySdDir(cid);
9885                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9886                 }
9887 
9888                 boolean mounted = PackageHelper.isContainerMounted(cid);
9889                 if (!mounted) {
9890                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
9891                 }
9892             }
9893             return status;
9894         }
9895 
cleanUp()9896         private void cleanUp() {
9897             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
9898 
9899             // Destroy secure container
9900             PackageHelper.destroySdDir(cid);
9901         }
9902 
getAllCodePaths()9903         private List<String> getAllCodePaths() {
9904             final File codeFile = new File(getCodePath());
9905             if (codeFile != null && codeFile.exists()) {
9906                 try {
9907                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9908                     return pkg.getAllCodePaths();
9909                 } catch (PackageParserException e) {
9910                     // Ignored; we tried our best
9911                 }
9912             }
9913             return Collections.EMPTY_LIST;
9914         }
9915 
cleanUpResourcesLI()9916         void cleanUpResourcesLI() {
9917             // Enumerate all code paths before deleting
9918             cleanUpResourcesLI(getAllCodePaths());
9919         }
9920 
cleanUpResourcesLI(List<String> allCodePaths)9921         private void cleanUpResourcesLI(List<String> allCodePaths) {
9922             cleanUp();
9923 
9924             if (!allCodePaths.isEmpty()) {
9925                 if (instructionSets == null) {
9926                     throw new IllegalStateException("instructionSet == null");
9927                 }
9928                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9929                 for (String codePath : allCodePaths) {
9930                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9931                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9932                         if (retCode < 0) {
9933                             Slog.w(TAG, "Couldn't remove dex file for package: "
9934                                     + " at location " + codePath + ", retcode=" + retCode);
9935                             // we don't consider this to be a failure of the core package deletion
9936                         }
9937                     }
9938                 }
9939             }
9940         }
9941 
matchContainer(String app)9942         boolean matchContainer(String app) {
9943             if (cid.startsWith(app)) {
9944                 return true;
9945             }
9946             return false;
9947         }
9948 
getPackageName()9949         String getPackageName() {
9950             return getAsecPackageName(cid);
9951         }
9952 
doPostDeleteLI(boolean delete)9953         boolean doPostDeleteLI(boolean delete) {
9954             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
9955             final List<String> allCodePaths = getAllCodePaths();
9956             boolean mounted = PackageHelper.isContainerMounted(cid);
9957             if (mounted) {
9958                 // Unmount first
9959                 if (PackageHelper.unMountSdDir(cid)) {
9960                     mounted = false;
9961                 }
9962             }
9963             if (!mounted && delete) {
9964                 cleanUpResourcesLI(allCodePaths);
9965             }
9966             return !mounted;
9967         }
9968 
9969         @Override
doPreCopy()9970         int doPreCopy() {
9971             if (isFwdLocked()) {
9972                 if (!PackageHelper.fixSdPermissions(cid,
9973                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
9974                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9975                 }
9976             }
9977 
9978             return PackageManager.INSTALL_SUCCEEDED;
9979         }
9980 
9981         @Override
doPostCopy(int uid)9982         int doPostCopy(int uid) {
9983             if (isFwdLocked()) {
9984                 if (uid < Process.FIRST_APPLICATION_UID
9985                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
9986                                 RES_FILE_NAME)) {
9987                     Slog.e(TAG, "Failed to finalize " + cid);
9988                     PackageHelper.destroySdDir(cid);
9989                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9990                 }
9991             }
9992 
9993             return PackageManager.INSTALL_SUCCEEDED;
9994         }
9995     }
9996 
getAsecPackageName(String packageCid)9997     static String getAsecPackageName(String packageCid) {
9998         int idx = packageCid.lastIndexOf("-");
9999         if (idx == -1) {
10000             return packageCid;
10001         }
10002         return packageCid.substring(0, idx);
10003     }
10004 
10005     // Utility method used to create code paths based on package name and available index.
getNextCodePath(String oldCodePath, String prefix, String suffix)10006     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
10007         String idxStr = "";
10008         int idx = 1;
10009         // Fall back to default value of idx=1 if prefix is not
10010         // part of oldCodePath
10011         if (oldCodePath != null) {
10012             String subStr = oldCodePath;
10013             // Drop the suffix right away
10014             if (suffix != null && subStr.endsWith(suffix)) {
10015                 subStr = subStr.substring(0, subStr.length() - suffix.length());
10016             }
10017             // If oldCodePath already contains prefix find out the
10018             // ending index to either increment or decrement.
10019             int sidx = subStr.lastIndexOf(prefix);
10020             if (sidx != -1) {
10021                 subStr = subStr.substring(sidx + prefix.length());
10022                 if (subStr != null) {
10023                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
10024                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
10025                     }
10026                     try {
10027                         idx = Integer.parseInt(subStr);
10028                         if (idx <= 1) {
10029                             idx++;
10030                         } else {
10031                             idx--;
10032                         }
10033                     } catch(NumberFormatException e) {
10034                     }
10035                 }
10036             }
10037         }
10038         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
10039         return prefix + idxStr;
10040     }
10041 
getNextCodePath(String packageName)10042     private File getNextCodePath(String packageName) {
10043         int suffix = 1;
10044         File result;
10045         do {
10046             result = new File(mAppInstallDir, packageName + "-" + suffix);
10047             suffix++;
10048         } while (result.exists());
10049         return result;
10050     }
10051 
10052     // Utility method used to ignore ADD/REMOVE events
10053     // by directory observer.
ignoreCodePath(String fullPathStr)10054     private static boolean ignoreCodePath(String fullPathStr) {
10055         String apkName = deriveCodePathName(fullPathStr);
10056         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
10057         if (idx != -1 && ((idx+1) < apkName.length())) {
10058             // Make sure the package ends with a numeral
10059             String version = apkName.substring(idx+1);
10060             try {
10061                 Integer.parseInt(version);
10062                 return true;
10063             } catch (NumberFormatException e) {}
10064         }
10065         return false;
10066     }
10067 
10068     // Utility method that returns the relative package path with respect
10069     // to the installation directory. Like say for /data/data/com.test-1.apk
10070     // string com.test-1 is returned.
deriveCodePathName(String codePath)10071     static String deriveCodePathName(String codePath) {
10072         if (codePath == null) {
10073             return null;
10074         }
10075         final File codeFile = new File(codePath);
10076         final String name = codeFile.getName();
10077         if (codeFile.isDirectory()) {
10078             return name;
10079         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
10080             final int lastDot = name.lastIndexOf('.');
10081             return name.substring(0, lastDot);
10082         } else {
10083             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
10084             return null;
10085         }
10086     }
10087 
10088     class PackageInstalledInfo {
10089         String name;
10090         int uid;
10091         // The set of users that originally had this package installed.
10092         int[] origUsers;
10093         // The set of users that now have this package installed.
10094         int[] newUsers;
10095         PackageParser.Package pkg;
10096         int returnCode;
10097         String returnMsg;
10098         PackageRemovedInfo removedInfo;
10099 
setError(int code, String msg)10100         public void setError(int code, String msg) {
10101             returnCode = code;
10102             returnMsg = msg;
10103             Slog.w(TAG, msg);
10104         }
10105 
setError(String msg, PackageParserException e)10106         public void setError(String msg, PackageParserException e) {
10107             returnCode = e.error;
10108             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
10109             Slog.w(TAG, msg, e);
10110         }
10111 
setError(String msg, PackageManagerException e)10112         public void setError(String msg, PackageManagerException e) {
10113             returnCode = e.error;
10114             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
10115             Slog.w(TAG, msg, e);
10116         }
10117 
10118         // In some error cases we want to convey more info back to the observer
10119         String origPackage;
10120         String origPermission;
10121     }
10122 
10123     /*
10124      * Install a non-existing package.
10125      */
installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res)10126     private void installNewPackageLI(PackageParser.Package pkg,
10127             int parseFlags, int scanFlags, UserHandle user,
10128             String installerPackageName, PackageInstalledInfo res) {
10129         // Remember this for later, in case we need to rollback this install
10130         String pkgName = pkg.packageName;
10131 
10132         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
10133         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
10134         synchronized(mPackages) {
10135             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
10136                 // A package with the same name is already installed, though
10137                 // it has been renamed to an older name.  The package we
10138                 // are trying to install should be installed as an update to
10139                 // the existing one, but that has not been requested, so bail.
10140                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
10141                         + " without first uninstalling package running as "
10142                         + mSettings.mRenamedPackages.get(pkgName));
10143                 return;
10144             }
10145             if (mPackages.containsKey(pkgName)) {
10146                 // Don't allow installation over an existing package with the same name.
10147                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
10148                         + " without first uninstalling.");
10149                 return;
10150             }
10151         }
10152 
10153         try {
10154             PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
10155                     System.currentTimeMillis(), user);
10156 
10157             updateSettingsLI(newPackage, installerPackageName, null, null, res);
10158             // delete the partially installed application. the data directory will have to be
10159             // restored if it was already existing
10160             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10161                 // remove package from internal structures.  Note that we want deletePackageX to
10162                 // delete the package data and cache directories that it created in
10163                 // scanPackageLocked, unless those directories existed before we even tried to
10164                 // install.
10165                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
10166                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
10167                                 res.removedInfo, true);
10168             }
10169 
10170         } catch (PackageManagerException e) {
10171             res.setError("Package couldn't be installed in " + pkg.codePath, e);
10172         }
10173     }
10174 
checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)10175     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
10176         // Upgrade keysets are being used.  Determine if new package has a superset of the
10177         // required keys.
10178         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
10179         KeySetManagerService ksms = mSettings.mKeySetManagerService;
10180         for (int i = 0; i < upgradeKeySets.length; i++) {
10181             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
10182             if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
10183                 return true;
10184             }
10185         }
10186         return false;
10187     }
10188 
replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res)10189     private void replacePackageLI(PackageParser.Package pkg,
10190             int parseFlags, int scanFlags, UserHandle user,
10191             String installerPackageName, PackageInstalledInfo res) {
10192         PackageParser.Package oldPackage;
10193         String pkgName = pkg.packageName;
10194         int[] allUsers;
10195         boolean[] perUserInstalled;
10196 
10197         // First find the old package info and check signatures
10198         synchronized(mPackages) {
10199             oldPackage = mPackages.get(pkgName);
10200             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
10201             PackageSetting ps = mSettings.mPackages.get(pkgName);
10202             if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10203                 // default to original signature matching
10204                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
10205                     != PackageManager.SIGNATURE_MATCH) {
10206                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10207                             "New package has a different signature: " + pkgName);
10208                     return;
10209                 }
10210             } else {
10211                 if(!checkUpgradeKeySetLP(ps, pkg)) {
10212                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10213                             "New package not signed by keys specified by upgrade-keysets: "
10214                             + pkgName);
10215                     return;
10216                 }
10217             }
10218 
10219             // In case of rollback, remember per-user/profile install state
10220             allUsers = sUserManager.getUserIds();
10221             perUserInstalled = new boolean[allUsers.length];
10222             for (int i = 0; i < allUsers.length; i++) {
10223                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10224             }
10225         }
10226 
10227         boolean sysPkg = (isSystemApp(oldPackage));
10228         if (sysPkg) {
10229             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10230                     user, allUsers, perUserInstalled, installerPackageName, res);
10231         } else {
10232             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10233                     user, allUsers, perUserInstalled, installerPackageName, res);
10234         }
10235     }
10236 
replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, PackageInstalledInfo res)10237     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
10238             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10239             int[] allUsers, boolean[] perUserInstalled,
10240             String installerPackageName, PackageInstalledInfo res) {
10241         String pkgName = deletedPackage.packageName;
10242         boolean deletedPkg = true;
10243         boolean updatedSettings = false;
10244 
10245         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
10246                 + deletedPackage);
10247         long origUpdateTime;
10248         if (pkg.mExtras != null) {
10249             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
10250         } else {
10251             origUpdateTime = 0;
10252         }
10253 
10254         // First delete the existing package while retaining the data directory
10255         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
10256                 res.removedInfo, true)) {
10257             // If the existing package wasn't successfully deleted
10258             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
10259             deletedPkg = false;
10260         } else {
10261             // Successfully deleted the old package; proceed with replace.
10262 
10263             // If deleted package lived in a container, give users a chance to
10264             // relinquish resources before killing.
10265             if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
10266                 if (DEBUG_INSTALL) {
10267                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
10268                 }
10269                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
10270                 final ArrayList<String> pkgList = new ArrayList<String>(1);
10271                 pkgList.add(deletedPackage.applicationInfo.packageName);
10272                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
10273             }
10274 
10275             deleteCodeCacheDirsLI(pkgName);
10276             try {
10277                 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
10278                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
10279                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10280                 updatedSettings = true;
10281             } catch (PackageManagerException e) {
10282                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10283             }
10284         }
10285 
10286         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10287             // remove package from internal structures.  Note that we want deletePackageX to
10288             // delete the package data and cache directories that it created in
10289             // scanPackageLocked, unless those directories existed before we even tried to
10290             // install.
10291             if(updatedSettings) {
10292                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
10293                 deletePackageLI(
10294                         pkgName, null, true, allUsers, perUserInstalled,
10295                         PackageManager.DELETE_KEEP_DATA,
10296                                 res.removedInfo, true);
10297             }
10298             // Since we failed to install the new package we need to restore the old
10299             // package that we deleted.
10300             if (deletedPkg) {
10301                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
10302                 File restoreFile = new File(deletedPackage.codePath);
10303                 // Parse old package
10304                 boolean oldOnSd = isExternal(deletedPackage);
10305                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
10306                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
10307                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
10308                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
10309                 try {
10310                     scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
10311                 } catch (PackageManagerException e) {
10312                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
10313                             + e.getMessage());
10314                     return;
10315                 }
10316                 // Restore of old package succeeded. Update permissions.
10317                 // writer
10318                 synchronized (mPackages) {
10319                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
10320                             UPDATE_PERMISSIONS_ALL);
10321                     // can downgrade to reader
10322                     mSettings.writeLPr();
10323                 }
10324                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
10325             }
10326         }
10327     }
10328 
replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, PackageInstalledInfo res)10329     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
10330             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10331             int[] allUsers, boolean[] perUserInstalled,
10332             String installerPackageName, PackageInstalledInfo res) {
10333         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
10334                 + ", old=" + deletedPackage);
10335         boolean disabledSystem = false;
10336         boolean updatedSettings = false;
10337         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
10338         if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
10339             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10340         }
10341         String packageName = deletedPackage.packageName;
10342         if (packageName == null) {
10343             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10344                     "Attempt to delete null packageName.");
10345             return;
10346         }
10347         PackageParser.Package oldPkg;
10348         PackageSetting oldPkgSetting;
10349         // reader
10350         synchronized (mPackages) {
10351             oldPkg = mPackages.get(packageName);
10352             oldPkgSetting = mSettings.mPackages.get(packageName);
10353             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
10354                     (oldPkgSetting == null)) {
10355                 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10356                         "Couldn't find package:" + packageName + " information");
10357                 return;
10358             }
10359         }
10360 
10361         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
10362 
10363         res.removedInfo.uid = oldPkg.applicationInfo.uid;
10364         res.removedInfo.removedPackage = packageName;
10365         // Remove existing system package
10366         removePackageLI(oldPkgSetting, true);
10367         // writer
10368         synchronized (mPackages) {
10369             disabledSystem = mSettings.disableSystemPackageLPw(packageName);
10370             if (!disabledSystem && deletedPackage != null) {
10371                 // We didn't need to disable the .apk as a current system package,
10372                 // which means we are replacing another update that is already
10373                 // installed.  We need to make sure to delete the older one's .apk.
10374                 res.removedInfo.args = createInstallArgsForExisting(0,
10375                         deletedPackage.applicationInfo.getCodePath(),
10376                         deletedPackage.applicationInfo.getResourcePath(),
10377                         deletedPackage.applicationInfo.nativeLibraryRootDir,
10378                         getAppDexInstructionSets(deletedPackage.applicationInfo));
10379             } else {
10380                 res.removedInfo.args = null;
10381             }
10382         }
10383 
10384         // Successfully disabled the old package. Now proceed with re-installation
10385         deleteCodeCacheDirsLI(packageName);
10386 
10387         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10388         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10389 
10390         PackageParser.Package newPackage = null;
10391         try {
10392             newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
10393             if (newPackage.mExtras != null) {
10394                 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
10395                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
10396                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
10397 
10398                 // is the update attempting to change shared user? that isn't going to work...
10399                 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
10400                     res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
10401                             "Forbidding shared user change from " + oldPkgSetting.sharedUser
10402                             + " to " + newPkgSetting.sharedUser);
10403                     updatedSettings = true;
10404                 }
10405             }
10406 
10407             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10408                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10409                 updatedSettings = true;
10410             }
10411 
10412         } catch (PackageManagerException e) {
10413             res.setError("Package couldn't be installed in " + pkg.codePath, e);
10414         }
10415 
10416         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10417             // Re installation failed. Restore old information
10418             // Remove new pkg information
10419             if (newPackage != null) {
10420                 removeInstalledPackageLI(newPackage, true);
10421             }
10422             // Add back the old system package
10423             try {
10424                 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
10425             } catch (PackageManagerException e) {
10426                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
10427             }
10428             // Restore the old system information in Settings
10429             synchronized (mPackages) {
10430                 if (disabledSystem) {
10431                     mSettings.enableSystemPackageLPw(packageName);
10432                 }
10433                 if (updatedSettings) {
10434                     mSettings.setInstallerPackageName(packageName,
10435                             oldPkgSetting.installerPackageName);
10436                 }
10437                 mSettings.writeLPr();
10438             }
10439         }
10440     }
10441 
updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res)10442     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
10443             int[] allUsers, boolean[] perUserInstalled,
10444             PackageInstalledInfo res) {
10445         String pkgName = newPackage.packageName;
10446         synchronized (mPackages) {
10447             //write settings. the installStatus will be incomplete at this stage.
10448             //note that the new package setting would have already been
10449             //added to mPackages. It hasn't been persisted yet.
10450             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
10451             mSettings.writeLPr();
10452         }
10453 
10454         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
10455 
10456         synchronized (mPackages) {
10457             updatePermissionsLPw(newPackage.packageName, newPackage,
10458                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
10459                             ? UPDATE_PERMISSIONS_ALL : 0));
10460             // For system-bundled packages, we assume that installing an upgraded version
10461             // of the package implies that the user actually wants to run that new code,
10462             // so we enable the package.
10463             if (isSystemApp(newPackage)) {
10464                 // NB: implicit assumption that system package upgrades apply to all users
10465                 if (DEBUG_INSTALL) {
10466                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
10467                 }
10468                 PackageSetting ps = mSettings.mPackages.get(pkgName);
10469                 if (ps != null) {
10470                     if (res.origUsers != null) {
10471                         for (int userHandle : res.origUsers) {
10472                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
10473                                     userHandle, installerPackageName);
10474                         }
10475                     }
10476                     // Also convey the prior install/uninstall state
10477                     if (allUsers != null && perUserInstalled != null) {
10478                         for (int i = 0; i < allUsers.length; i++) {
10479                             if (DEBUG_INSTALL) {
10480                                 Slog.d(TAG, "    user " + allUsers[i]
10481                                         + " => " + perUserInstalled[i]);
10482                             }
10483                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
10484                         }
10485                         // these install state changes will be persisted in the
10486                         // upcoming call to mSettings.writeLPr().
10487                     }
10488                 }
10489             }
10490             res.name = pkgName;
10491             res.uid = newPackage.applicationInfo.uid;
10492             res.pkg = newPackage;
10493             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
10494             mSettings.setInstallerPackageName(pkgName, installerPackageName);
10495             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10496             //to update install status
10497             mSettings.writeLPr();
10498         }
10499     }
10500 
installPackageLI(InstallArgs args, PackageInstalledInfo res)10501     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
10502         final int installFlags = args.installFlags;
10503         String installerPackageName = args.installerPackageName;
10504         File tmpPackageFile = new File(args.getCodePath());
10505         boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
10506         boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
10507         boolean replace = false;
10508         final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
10509         // Result object to be returned
10510         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10511 
10512         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
10513         // Retrieve PackageSettings and parse package
10514         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
10515                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
10516                 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
10517         PackageParser pp = new PackageParser();
10518         pp.setSeparateProcesses(mSeparateProcesses);
10519         pp.setDisplayMetrics(mMetrics);
10520 
10521         final PackageParser.Package pkg;
10522         try {
10523             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
10524         } catch (PackageParserException e) {
10525             res.setError("Failed parse during installPackageLI", e);
10526             return;
10527         }
10528 
10529         // Mark that we have an install time CPU ABI override.
10530         pkg.cpuAbiOverride = args.abiOverride;
10531 
10532         String pkgName = res.name = pkg.packageName;
10533         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
10534             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
10535                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
10536                 return;
10537             }
10538         }
10539 
10540         try {
10541             pp.collectCertificates(pkg, parseFlags);
10542             pp.collectManifestDigest(pkg);
10543         } catch (PackageParserException e) {
10544             res.setError("Failed collect during installPackageLI", e);
10545             return;
10546         }
10547 
10548         /* If the installer passed in a manifest digest, compare it now. */
10549         if (args.manifestDigest != null) {
10550             if (DEBUG_INSTALL) {
10551                 final String parsedManifest = pkg.manifestDigest == null ? "null"
10552                         : pkg.manifestDigest.toString();
10553                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
10554                         + parsedManifest);
10555             }
10556 
10557             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
10558                 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
10559                 return;
10560             }
10561         } else if (DEBUG_INSTALL) {
10562             final String parsedManifest = pkg.manifestDigest == null
10563                     ? "null" : pkg.manifestDigest.toString();
10564             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
10565         }
10566 
10567         // Get rid of all references to package scan path via parser.
10568         pp = null;
10569         String oldCodePath = null;
10570         boolean systemApp = false;
10571         synchronized (mPackages) {
10572             // Check if installing already existing package
10573             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10574                 String oldName = mSettings.mRenamedPackages.get(pkgName);
10575                 if (pkg.mOriginalPackages != null
10576                         && pkg.mOriginalPackages.contains(oldName)
10577                         && mPackages.containsKey(oldName)) {
10578                     // This package is derived from an original package,
10579                     // and this device has been updating from that original
10580                     // name.  We must continue using the original name, so
10581                     // rename the new package here.
10582                     pkg.setPackageName(oldName);
10583                     pkgName = pkg.packageName;
10584                     replace = true;
10585                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
10586                             + oldName + " pkgName=" + pkgName);
10587                 } else if (mPackages.containsKey(pkgName)) {
10588                     // This package, under its official name, already exists
10589                     // on the device; we should replace it.
10590                     replace = true;
10591                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
10592                 }
10593             }
10594 
10595             PackageSetting ps = mSettings.mPackages.get(pkgName);
10596             if (ps != null) {
10597                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
10598 
10599                 // Quick sanity check that we're signed correctly if updating;
10600                 // we'll check this again later when scanning, but we want to
10601                 // bail early here before tripping over redefined permissions.
10602                 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10603                     try {
10604                         verifySignaturesLP(ps, pkg);
10605                     } catch (PackageManagerException e) {
10606                         res.setError(e.error, e.getMessage());
10607                         return;
10608                     }
10609                 } else {
10610                     if (!checkUpgradeKeySetLP(ps, pkg)) {
10611                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
10612                                 + pkg.packageName + " upgrade keys do not match the "
10613                                 + "previously installed version");
10614                         return;
10615                     }
10616                 }
10617 
10618                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
10619                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
10620                     systemApp = (ps.pkg.applicationInfo.flags &
10621                             ApplicationInfo.FLAG_SYSTEM) != 0;
10622                 }
10623                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10624             }
10625 
10626             // Check whether the newly-scanned package wants to define an already-defined perm
10627             int N = pkg.permissions.size();
10628             for (int i = N-1; i >= 0; i--) {
10629                 PackageParser.Permission perm = pkg.permissions.get(i);
10630                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
10631                 if (bp != null) {
10632                     // If the defining package is signed with our cert, it's okay.  This
10633                     // also includes the "updating the same package" case, of course.
10634                     // "updating same package" could also involve key-rotation.
10635                     final boolean sigsOk;
10636                     if (!bp.sourcePackage.equals(pkg.packageName)
10637                             || !(bp.packageSetting instanceof PackageSetting)
10638                             || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
10639                             || ((PackageSetting) bp.packageSetting).sharedUser != null) {
10640                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
10641                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
10642                     } else {
10643                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
10644                     }
10645                     if (!sigsOk) {
10646                         // If the owning package is the system itself, we log but allow
10647                         // install to proceed; we fail the install on all other permission
10648                         // redefinitions.
10649                         if (!bp.sourcePackage.equals("android")) {
10650                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
10651                                     + pkg.packageName + " attempting to redeclare permission "
10652                                     + perm.info.name + " already owned by " + bp.sourcePackage);
10653                             res.origPermission = perm.info.name;
10654                             res.origPackage = bp.sourcePackage;
10655                             return;
10656                         } else {
10657                             Slog.w(TAG, "Package " + pkg.packageName
10658                                     + " attempting to redeclare system permission "
10659                                     + perm.info.name + "; ignoring new declaration");
10660                             pkg.permissions.remove(i);
10661                         }
10662                     }
10663                 }
10664             }
10665 
10666         }
10667 
10668         if (systemApp && onSd) {
10669             // Disable updates to system apps on sdcard
10670             res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10671                     "Cannot install updates to system apps on sdcard");
10672             return;
10673         }
10674 
10675         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
10676             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
10677             return;
10678         }
10679 
10680         if (replace) {
10681             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
10682                     installerPackageName, res);
10683         } else {
10684             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
10685                     args.user, installerPackageName, res);
10686         }
10687         synchronized (mPackages) {
10688             final PackageSetting ps = mSettings.mPackages.get(pkgName);
10689             if (ps != null) {
10690                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10691             }
10692         }
10693     }
10694 
isForwardLocked(PackageParser.Package pkg)10695     private static boolean isForwardLocked(PackageParser.Package pkg) {
10696         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10697     }
10698 
isForwardLocked(ApplicationInfo info)10699     private static boolean isForwardLocked(ApplicationInfo info) {
10700         return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10701     }
10702 
isForwardLocked(PackageSetting ps)10703     private boolean isForwardLocked(PackageSetting ps) {
10704         return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10705     }
10706 
isMultiArch(PackageSetting ps)10707     private static boolean isMultiArch(PackageSetting ps) {
10708         return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10709     }
10710 
isMultiArch(ApplicationInfo info)10711     private static boolean isMultiArch(ApplicationInfo info) {
10712         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10713     }
10714 
isExternal(PackageParser.Package pkg)10715     private static boolean isExternal(PackageParser.Package pkg) {
10716         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10717     }
10718 
isExternal(PackageSetting ps)10719     private static boolean isExternal(PackageSetting ps) {
10720         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10721     }
10722 
isExternal(ApplicationInfo info)10723     private static boolean isExternal(ApplicationInfo info) {
10724         return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10725     }
10726 
isSystemApp(PackageParser.Package pkg)10727     private static boolean isSystemApp(PackageParser.Package pkg) {
10728         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10729     }
10730 
isPrivilegedApp(PackageParser.Package pkg)10731     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
10732         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
10733     }
10734 
isSystemApp(ApplicationInfo info)10735     private static boolean isSystemApp(ApplicationInfo info) {
10736         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10737     }
10738 
isSystemApp(PackageSetting ps)10739     private static boolean isSystemApp(PackageSetting ps) {
10740         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
10741     }
10742 
isUpdatedSystemApp(PackageSetting ps)10743     private static boolean isUpdatedSystemApp(PackageSetting ps) {
10744         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10745     }
10746 
isUpdatedSystemApp(PackageParser.Package pkg)10747     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
10748         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10749     }
10750 
isUpdatedSystemApp(ApplicationInfo info)10751     private static boolean isUpdatedSystemApp(ApplicationInfo info) {
10752         return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10753     }
10754 
packageFlagsToInstallFlags(PackageSetting ps)10755     private int packageFlagsToInstallFlags(PackageSetting ps) {
10756         int installFlags = 0;
10757         if (isExternal(ps)) {
10758             installFlags |= PackageManager.INSTALL_EXTERNAL;
10759         }
10760         if (isForwardLocked(ps)) {
10761             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10762         }
10763         return installFlags;
10764     }
10765 
deleteTempPackageFiles()10766     private void deleteTempPackageFiles() {
10767         final FilenameFilter filter = new FilenameFilter() {
10768             public boolean accept(File dir, String name) {
10769                 return name.startsWith("vmdl") && name.endsWith(".tmp");
10770             }
10771         };
10772         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
10773             file.delete();
10774         }
10775     }
10776 
10777     @Override
deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, int flags)10778     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
10779             int flags) {
10780         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
10781                 flags);
10782     }
10783 
10784     @Override
deletePackage(final String packageName, final IPackageDeleteObserver2 observer, final int userId, final int flags)10785     public void deletePackage(final String packageName,
10786             final IPackageDeleteObserver2 observer, final int userId, final int flags) {
10787         mContext.enforceCallingOrSelfPermission(
10788                 android.Manifest.permission.DELETE_PACKAGES, null);
10789         final int uid = Binder.getCallingUid();
10790         if (UserHandle.getUserId(uid) != userId) {
10791             mContext.enforceCallingPermission(
10792                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10793                     "deletePackage for user " + userId);
10794         }
10795         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
10796             try {
10797                 observer.onPackageDeleted(packageName,
10798                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
10799             } catch (RemoteException re) {
10800             }
10801             return;
10802         }
10803 
10804         boolean uninstallBlocked = false;
10805         if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
10806             int[] users = sUserManager.getUserIds();
10807             for (int i = 0; i < users.length; ++i) {
10808                 if (getBlockUninstallForUser(packageName, users[i])) {
10809                     uninstallBlocked = true;
10810                     break;
10811                 }
10812             }
10813         } else {
10814             uninstallBlocked = getBlockUninstallForUser(packageName, userId);
10815         }
10816         if (uninstallBlocked) {
10817             try {
10818                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
10819                         null);
10820             } catch (RemoteException re) {
10821             }
10822             return;
10823         }
10824 
10825         if (DEBUG_REMOVE) {
10826             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
10827         }
10828         // Queue up an async operation since the package deletion may take a little while.
10829         mHandler.post(new Runnable() {
10830             public void run() {
10831                 mHandler.removeCallbacks(this);
10832                 final int returnCode = deletePackageX(packageName, userId, flags);
10833                 if (observer != null) {
10834                     try {
10835                         observer.onPackageDeleted(packageName, returnCode, null);
10836                     } catch (RemoteException e) {
10837                         Log.i(TAG, "Observer no longer exists.");
10838                     } //end catch
10839                 } //end if
10840             } //end run
10841         });
10842     }
10843 
isPackageDeviceAdmin(String packageName, int userId)10844     private boolean isPackageDeviceAdmin(String packageName, int userId) {
10845         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
10846                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
10847         try {
10848             if (dpm != null) {
10849                 if (dpm.isDeviceOwner(packageName)) {
10850                     return true;
10851                 }
10852                 int[] users;
10853                 if (userId == UserHandle.USER_ALL) {
10854                     users = sUserManager.getUserIds();
10855                 } else {
10856                     users = new int[]{userId};
10857                 }
10858                 for (int i = 0; i < users.length; ++i) {
10859                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
10860                         return true;
10861                     }
10862                 }
10863             }
10864         } catch (RemoteException e) {
10865         }
10866         return false;
10867     }
10868 
10869     /**
10870      *  This method is an internal method that could be get invoked either
10871      *  to delete an installed package or to clean up a failed installation.
10872      *  After deleting an installed package, a broadcast is sent to notify any
10873      *  listeners that the package has been installed. For cleaning up a failed
10874      *  installation, the broadcast is not necessary since the package's
10875      *  installation wouldn't have sent the initial broadcast either
10876      *  The key steps in deleting a package are
10877      *  deleting the package information in internal structures like mPackages,
10878      *  deleting the packages base directories through installd
10879      *  updating mSettings to reflect current status
10880      *  persisting settings for later use
10881      *  sending a broadcast if necessary
10882      */
deletePackageX(String packageName, int userId, int flags)10883     private int deletePackageX(String packageName, int userId, int flags) {
10884         final PackageRemovedInfo info = new PackageRemovedInfo();
10885         final boolean res;
10886 
10887         final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
10888                 ? UserHandle.ALL : new UserHandle(userId);
10889 
10890         if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
10891             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
10892             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
10893         }
10894 
10895         boolean removedForAllUsers = false;
10896         boolean systemUpdate = false;
10897 
10898         // for the uninstall-updates case and restricted profiles, remember the per-
10899         // userhandle installed state
10900         int[] allUsers;
10901         boolean[] perUserInstalled;
10902         synchronized (mPackages) {
10903             PackageSetting ps = mSettings.mPackages.get(packageName);
10904             allUsers = sUserManager.getUserIds();
10905             perUserInstalled = new boolean[allUsers.length];
10906             for (int i = 0; i < allUsers.length; i++) {
10907                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10908             }
10909         }
10910 
10911         synchronized (mInstallLock) {
10912             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
10913             res = deletePackageLI(packageName, removeForUser,
10914                     true, allUsers, perUserInstalled,
10915                     flags | REMOVE_CHATTY, info, true);
10916             systemUpdate = info.isRemovedPackageSystemUpdate;
10917             if (res && !systemUpdate && mPackages.get(packageName) == null) {
10918                 removedForAllUsers = true;
10919             }
10920             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
10921                     + " removedForAllUsers=" + removedForAllUsers);
10922         }
10923 
10924         if (res) {
10925             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
10926 
10927             // If the removed package was a system update, the old system package
10928             // was re-enabled; we need to broadcast this information
10929             if (systemUpdate) {
10930                 Bundle extras = new Bundle(1);
10931                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
10932                         ? info.removedAppId : info.uid);
10933                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10934 
10935                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
10936                         extras, null, null, null);
10937                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
10938                         extras, null, null, null);
10939                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
10940                         null, packageName, null, null);
10941             }
10942         }
10943         // Force a gc here.
10944         Runtime.getRuntime().gc();
10945         // Delete the resources here after sending the broadcast to let
10946         // other processes clean up before deleting resources.
10947         if (info.args != null) {
10948             synchronized (mInstallLock) {
10949                 info.args.doPostDeleteLI(true);
10950             }
10951         }
10952 
10953         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
10954     }
10955 
10956     static class PackageRemovedInfo {
10957         String removedPackage;
10958         int uid = -1;
10959         int removedAppId = -1;
10960         int[] removedUsers = null;
10961         boolean isRemovedPackageSystemUpdate = false;
10962         // Clean up resources deleted packages.
10963         InstallArgs args = null;
10964 
sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers)10965         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
10966             Bundle extras = new Bundle(1);
10967             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
10968             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
10969             if (replacing) {
10970                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10971             }
10972             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
10973             if (removedPackage != null) {
10974                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
10975                         extras, null, null, removedUsers);
10976                 if (fullRemove && !replacing) {
10977                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
10978                             extras, null, null, removedUsers);
10979                 }
10980             }
10981             if (removedAppId >= 0) {
10982                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
10983                         removedUsers);
10984             }
10985         }
10986     }
10987 
10988     /*
10989      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
10990      * flag is not set, the data directory is removed as well.
10991      * make sure this flag is set for partially installed apps. If not its meaningless to
10992      * delete a partially installed application.
10993      */
removePackageDataLI(PackageSetting ps, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, int flags, boolean writeSettings)10994     private void removePackageDataLI(PackageSetting ps,
10995             int[] allUserHandles, boolean[] perUserInstalled,
10996             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
10997         String packageName = ps.name;
10998         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
10999         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
11000         // Retrieve object to delete permissions for shared user later on
11001         final PackageSetting deletedPs;
11002         // reader
11003         synchronized (mPackages) {
11004             deletedPs = mSettings.mPackages.get(packageName);
11005             if (outInfo != null) {
11006                 outInfo.removedPackage = packageName;
11007                 outInfo.removedUsers = deletedPs != null
11008                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
11009                         : null;
11010             }
11011         }
11012         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
11013             removeDataDirsLI(packageName);
11014             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
11015         }
11016         // writer
11017         synchronized (mPackages) {
11018             if (deletedPs != null) {
11019                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
11020                     if (outInfo != null) {
11021                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
11022                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
11023                     }
11024                     if (deletedPs != null) {
11025                         updatePermissionsLPw(deletedPs.name, null, 0);
11026                         if (deletedPs.sharedUser != null) {
11027                             // remove permissions associated with package
11028                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
11029                         }
11030                     }
11031                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
11032                 }
11033                 // make sure to preserve per-user disabled state if this removal was just
11034                 // a downgrade of a system app to the factory package
11035                 if (allUserHandles != null && perUserInstalled != null) {
11036                     if (DEBUG_REMOVE) {
11037                         Slog.d(TAG, "Propagating install state across downgrade");
11038                     }
11039                     for (int i = 0; i < allUserHandles.length; i++) {
11040                         if (DEBUG_REMOVE) {
11041                             Slog.d(TAG, "    user " + allUserHandles[i]
11042                                     + " => " + perUserInstalled[i]);
11043                         }
11044                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
11045                     }
11046                 }
11047             }
11048             // can downgrade to reader
11049             if (writeSettings) {
11050                 // Save settings now
11051                 mSettings.writeLPr();
11052             }
11053         }
11054         if (outInfo != null) {
11055             // A user ID was deleted here. Go through all users and remove it
11056             // from KeyStore.
11057             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
11058         }
11059     }
11060 
locationIsPrivileged(File path)11061     static boolean locationIsPrivileged(File path) {
11062         try {
11063             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
11064                     .getCanonicalPath();
11065             return path.getCanonicalPath().startsWith(privilegedAppDir);
11066         } catch (IOException e) {
11067             Slog.e(TAG, "Unable to access code path " + path);
11068         }
11069         return false;
11070     }
11071 
11072     /*
11073      * Tries to delete system package.
11074      */
deleteSystemPackageLI(PackageSetting newPs, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)11075     private boolean deleteSystemPackageLI(PackageSetting newPs,
11076             int[] allUserHandles, boolean[] perUserInstalled,
11077             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
11078         final boolean applyUserRestrictions
11079                 = (allUserHandles != null) && (perUserInstalled != null);
11080         PackageSetting disabledPs = null;
11081         // Confirm if the system package has been updated
11082         // An updated system app can be deleted. This will also have to restore
11083         // the system pkg from system partition
11084         // reader
11085         synchronized (mPackages) {
11086             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
11087         }
11088         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
11089                 + " disabledPs=" + disabledPs);
11090         if (disabledPs == null) {
11091             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
11092             return false;
11093         } else if (DEBUG_REMOVE) {
11094             Slog.d(TAG, "Deleting system pkg from data partition");
11095         }
11096         if (DEBUG_REMOVE) {
11097             if (applyUserRestrictions) {
11098                 Slog.d(TAG, "Remembering install states:");
11099                 for (int i = 0; i < allUserHandles.length; i++) {
11100                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
11101                 }
11102             }
11103         }
11104         // Delete the updated package
11105         outInfo.isRemovedPackageSystemUpdate = true;
11106         if (disabledPs.versionCode < newPs.versionCode) {
11107             // Delete data for downgrades
11108             flags &= ~PackageManager.DELETE_KEEP_DATA;
11109         } else {
11110             // Preserve data by setting flag
11111             flags |= PackageManager.DELETE_KEEP_DATA;
11112         }
11113         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
11114                 allUserHandles, perUserInstalled, outInfo, writeSettings);
11115         if (!ret) {
11116             return false;
11117         }
11118         // writer
11119         synchronized (mPackages) {
11120             // Reinstate the old system package
11121             mSettings.enableSystemPackageLPw(newPs.name);
11122             // Remove any native libraries from the upgraded package.
11123             NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
11124         }
11125         // Install the system package
11126         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
11127         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
11128         if (locationIsPrivileged(disabledPs.codePath)) {
11129             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
11130         }
11131 
11132         final PackageParser.Package newPkg;
11133         try {
11134             newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
11135         } catch (PackageManagerException e) {
11136             Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
11137             return false;
11138         }
11139 
11140         // writer
11141         synchronized (mPackages) {
11142             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
11143             updatePermissionsLPw(newPkg.packageName, newPkg,
11144                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
11145             if (applyUserRestrictions) {
11146                 if (DEBUG_REMOVE) {
11147                     Slog.d(TAG, "Propagating install state across reinstall");
11148                 }
11149                 for (int i = 0; i < allUserHandles.length; i++) {
11150                     if (DEBUG_REMOVE) {
11151                         Slog.d(TAG, "    user " + allUserHandles[i]
11152                                 + " => " + perUserInstalled[i]);
11153                     }
11154                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
11155                 }
11156                 // Regardless of writeSettings we need to ensure that this restriction
11157                 // state propagation is persisted
11158                 mSettings.writeAllUsersPackageRestrictionsLPr();
11159             }
11160             // can downgrade to reader here
11161             if (writeSettings) {
11162                 mSettings.writeLPr();
11163             }
11164         }
11165         return true;
11166     }
11167 
deleteInstalledPackageLI(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, boolean writeSettings)11168     private boolean deleteInstalledPackageLI(PackageSetting ps,
11169             boolean deleteCodeAndResources, int flags,
11170             int[] allUserHandles, boolean[] perUserInstalled,
11171             PackageRemovedInfo outInfo, boolean writeSettings) {
11172         if (outInfo != null) {
11173             outInfo.uid = ps.appId;
11174         }
11175 
11176         // Delete package data from internal structures and also remove data if flag is set
11177         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
11178 
11179         // Delete application code and resources
11180         if (deleteCodeAndResources && (outInfo != null)) {
11181             outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
11182                     ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
11183                     getAppDexInstructionSets(ps));
11184             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
11185         }
11186         return true;
11187     }
11188 
11189     @Override
setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)11190     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
11191             int userId) {
11192         mContext.enforceCallingOrSelfPermission(
11193                 android.Manifest.permission.DELETE_PACKAGES, null);
11194         synchronized (mPackages) {
11195             PackageSetting ps = mSettings.mPackages.get(packageName);
11196             if (ps == null) {
11197                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
11198                 return false;
11199             }
11200             if (!ps.getInstalled(userId)) {
11201                 // Can't block uninstall for an app that is not installed or enabled.
11202                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
11203                 return false;
11204             }
11205             ps.setBlockUninstall(blockUninstall, userId);
11206             mSettings.writePackageRestrictionsLPr(userId);
11207         }
11208         return true;
11209     }
11210 
11211     @Override
getBlockUninstallForUser(String packageName, int userId)11212     public boolean getBlockUninstallForUser(String packageName, int userId) {
11213         synchronized (mPackages) {
11214             PackageSetting ps = mSettings.mPackages.get(packageName);
11215             if (ps == null) {
11216                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
11217                 return false;
11218             }
11219             return ps.getBlockUninstall(userId);
11220         }
11221     }
11222 
11223     /*
11224      * This method handles package deletion in general
11225      */
deletePackageLI(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)11226     private boolean deletePackageLI(String packageName, UserHandle user,
11227             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
11228             int flags, PackageRemovedInfo outInfo,
11229             boolean writeSettings) {
11230         if (packageName == null) {
11231             Slog.w(TAG, "Attempt to delete null packageName.");
11232             return false;
11233         }
11234         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
11235         PackageSetting ps;
11236         boolean dataOnly = false;
11237         int removeUser = -1;
11238         int appId = -1;
11239         synchronized (mPackages) {
11240             ps = mSettings.mPackages.get(packageName);
11241             if (ps == null) {
11242                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11243                 return false;
11244             }
11245             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
11246                     && user.getIdentifier() != UserHandle.USER_ALL) {
11247                 // The caller is asking that the package only be deleted for a single
11248                 // user.  To do this, we just mark its uninstalled state and delete
11249                 // its data.  If this is a system app, we only allow this to happen if
11250                 // they have set the special DELETE_SYSTEM_APP which requests different
11251                 // semantics than normal for uninstalling system apps.
11252                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
11253                 ps.setUserState(user.getIdentifier(),
11254                         COMPONENT_ENABLED_STATE_DEFAULT,
11255                         false, //installed
11256                         true,  //stopped
11257                         true,  //notLaunched
11258                         false, //hidden
11259                         null, null, null,
11260                         false // blockUninstall
11261                         );
11262                 if (!isSystemApp(ps)) {
11263                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
11264                         // Other user still have this package installed, so all
11265                         // we need to do is clear this user's data and save that
11266                         // it is uninstalled.
11267                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
11268                         removeUser = user.getIdentifier();
11269                         appId = ps.appId;
11270                         mSettings.writePackageRestrictionsLPr(removeUser);
11271                     } else {
11272                         // We need to set it back to 'installed' so the uninstall
11273                         // broadcasts will be sent correctly.
11274                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
11275                         ps.setInstalled(true, user.getIdentifier());
11276                     }
11277                 } else {
11278                     // This is a system app, so we assume that the
11279                     // other users still have this package installed, so all
11280                     // we need to do is clear this user's data and save that
11281                     // it is uninstalled.
11282                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
11283                     removeUser = user.getIdentifier();
11284                     appId = ps.appId;
11285                     mSettings.writePackageRestrictionsLPr(removeUser);
11286                 }
11287             }
11288         }
11289 
11290         if (removeUser >= 0) {
11291             // From above, we determined that we are deleting this only
11292             // for a single user.  Continue the work here.
11293             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
11294             if (outInfo != null) {
11295                 outInfo.removedPackage = packageName;
11296                 outInfo.removedAppId = appId;
11297                 outInfo.removedUsers = new int[] {removeUser};
11298             }
11299             mInstaller.clearUserData(packageName, removeUser);
11300             removeKeystoreDataIfNeeded(removeUser, appId);
11301             schedulePackageCleaning(packageName, removeUser, false);
11302             return true;
11303         }
11304 
11305         if (dataOnly) {
11306             // Delete application data first
11307             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
11308             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
11309             return true;
11310         }
11311 
11312         boolean ret = false;
11313         if (isSystemApp(ps)) {
11314             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
11315             // When an updated system application is deleted we delete the existing resources as well and
11316             // fall back to existing code in system partition
11317             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
11318                     flags, outInfo, writeSettings);
11319         } else {
11320             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
11321             // Kill application pre-emptively especially for apps on sd.
11322             killApplication(packageName, ps.appId, "uninstall pkg");
11323             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
11324                     allUserHandles, perUserInstalled,
11325                     outInfo, writeSettings);
11326         }
11327 
11328         return ret;
11329     }
11330 
11331     private final class ClearStorageConnection implements ServiceConnection {
11332         IMediaContainerService mContainerService;
11333 
11334         @Override
onServiceConnected(ComponentName name, IBinder service)11335         public void onServiceConnected(ComponentName name, IBinder service) {
11336             synchronized (this) {
11337                 mContainerService = IMediaContainerService.Stub.asInterface(service);
11338                 notifyAll();
11339             }
11340         }
11341 
11342         @Override
onServiceDisconnected(ComponentName name)11343         public void onServiceDisconnected(ComponentName name) {
11344         }
11345     }
11346 
clearExternalStorageDataSync(String packageName, int userId, boolean allData)11347     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
11348         final boolean mounted;
11349         if (Environment.isExternalStorageEmulated()) {
11350             mounted = true;
11351         } else {
11352             final String status = Environment.getExternalStorageState();
11353 
11354             mounted = status.equals(Environment.MEDIA_MOUNTED)
11355                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
11356         }
11357 
11358         if (!mounted) {
11359             return;
11360         }
11361 
11362         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
11363         int[] users;
11364         if (userId == UserHandle.USER_ALL) {
11365             users = sUserManager.getUserIds();
11366         } else {
11367             users = new int[] { userId };
11368         }
11369         final ClearStorageConnection conn = new ClearStorageConnection();
11370         if (mContext.bindServiceAsUser(
11371                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
11372             try {
11373                 for (int curUser : users) {
11374                     long timeout = SystemClock.uptimeMillis() + 5000;
11375                     synchronized (conn) {
11376                         long now = SystemClock.uptimeMillis();
11377                         while (conn.mContainerService == null && now < timeout) {
11378                             try {
11379                                 conn.wait(timeout - now);
11380                             } catch (InterruptedException e) {
11381                             }
11382                         }
11383                     }
11384                     if (conn.mContainerService == null) {
11385                         return;
11386                     }
11387 
11388                     final UserEnvironment userEnv = new UserEnvironment(curUser);
11389                     clearDirectory(conn.mContainerService,
11390                             userEnv.buildExternalStorageAppCacheDirs(packageName));
11391                     if (allData) {
11392                         clearDirectory(conn.mContainerService,
11393                                 userEnv.buildExternalStorageAppDataDirs(packageName));
11394                         clearDirectory(conn.mContainerService,
11395                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
11396                     }
11397                 }
11398             } finally {
11399                 mContext.unbindService(conn);
11400             }
11401         }
11402     }
11403 
11404     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)11405     public void clearApplicationUserData(final String packageName,
11406             final IPackageDataObserver observer, final int userId) {
11407         mContext.enforceCallingOrSelfPermission(
11408                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
11409         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
11410         // Queue up an async operation since the package deletion may take a little while.
11411         mHandler.post(new Runnable() {
11412             public void run() {
11413                 mHandler.removeCallbacks(this);
11414                 final boolean succeeded;
11415                 synchronized (mInstallLock) {
11416                     succeeded = clearApplicationUserDataLI(packageName, userId);
11417                 }
11418                 clearExternalStorageDataSync(packageName, userId, true);
11419                 if (succeeded) {
11420                     // invoke DeviceStorageMonitor's update method to clear any notifications
11421                     DeviceStorageMonitorInternal
11422                             dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
11423                     if (dsm != null) {
11424                         dsm.checkMemory();
11425                     }
11426                 }
11427                 if(observer != null) {
11428                     try {
11429                         observer.onRemoveCompleted(packageName, succeeded);
11430                     } catch (RemoteException e) {
11431                         Log.i(TAG, "Observer no longer exists.");
11432                     }
11433                 } //end if observer
11434             } //end run
11435         });
11436     }
11437 
clearApplicationUserDataLI(String packageName, int userId)11438     private boolean clearApplicationUserDataLI(String packageName, int userId) {
11439         if (packageName == null) {
11440             Slog.w(TAG, "Attempt to delete null packageName.");
11441             return false;
11442         }
11443 
11444         // Try finding details about the requested package
11445         PackageParser.Package pkg;
11446         synchronized (mPackages) {
11447             pkg = mPackages.get(packageName);
11448             if (pkg == null) {
11449                 final PackageSetting ps = mSettings.mPackages.get(packageName);
11450                 if (ps != null) {
11451                     pkg = ps.pkg;
11452                 }
11453             }
11454         }
11455 
11456         if (pkg == null) {
11457             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11458         }
11459 
11460         // Always delete data directories for package, even if we found no other
11461         // record of app. This helps users recover from UID mismatches without
11462         // resorting to a full data wipe.
11463         int retCode = mInstaller.clearUserData(packageName, userId);
11464         if (retCode < 0) {
11465             Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
11466             return false;
11467         }
11468 
11469         if (pkg == null) {
11470             return false;
11471         }
11472 
11473         if (pkg != null && pkg.applicationInfo != null) {
11474             final int appId = pkg.applicationInfo.uid;
11475             removeKeystoreDataIfNeeded(userId, appId);
11476         }
11477 
11478         // Create a native library symlink only if we have native libraries
11479         // and if the native libraries are 32 bit libraries. We do not provide
11480         // this symlink for 64 bit libraries.
11481         if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
11482                 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
11483             final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
11484             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
11485                 Slog.w(TAG, "Failed linking native library dir");
11486                 return false;
11487             }
11488         }
11489 
11490         return true;
11491     }
11492 
11493     /**
11494      * Remove entries from the keystore daemon. Will only remove it if the
11495      * {@code appId} is valid.
11496      */
removeKeystoreDataIfNeeded(int userId, int appId)11497     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
11498         if (appId < 0) {
11499             return;
11500         }
11501 
11502         final KeyStore keyStore = KeyStore.getInstance();
11503         if (keyStore != null) {
11504             if (userId == UserHandle.USER_ALL) {
11505                 for (final int individual : sUserManager.getUserIds()) {
11506                     keyStore.clearUid(UserHandle.getUid(individual, appId));
11507                 }
11508             } else {
11509                 keyStore.clearUid(UserHandle.getUid(userId, appId));
11510             }
11511         } else {
11512             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
11513         }
11514     }
11515 
11516     @Override
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)11517     public void deleteApplicationCacheFiles(final String packageName,
11518             final IPackageDataObserver observer) {
11519         mContext.enforceCallingOrSelfPermission(
11520                 android.Manifest.permission.DELETE_CACHE_FILES, null);
11521         // Queue up an async operation since the package deletion may take a little while.
11522         final int userId = UserHandle.getCallingUserId();
11523         mHandler.post(new Runnable() {
11524             public void run() {
11525                 mHandler.removeCallbacks(this);
11526                 final boolean succeded;
11527                 synchronized (mInstallLock) {
11528                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
11529                 }
11530                 clearExternalStorageDataSync(packageName, userId, false);
11531                 if(observer != null) {
11532                     try {
11533                         observer.onRemoveCompleted(packageName, succeded);
11534                     } catch (RemoteException e) {
11535                         Log.i(TAG, "Observer no longer exists.");
11536                     }
11537                 } //end if observer
11538             } //end run
11539         });
11540     }
11541 
deleteApplicationCacheFilesLI(String packageName, int userId)11542     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
11543         if (packageName == null) {
11544             Slog.w(TAG, "Attempt to delete null packageName.");
11545             return false;
11546         }
11547         PackageParser.Package p;
11548         synchronized (mPackages) {
11549             p = mPackages.get(packageName);
11550         }
11551         if (p == null) {
11552             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11553             return false;
11554         }
11555         final ApplicationInfo applicationInfo = p.applicationInfo;
11556         if (applicationInfo == null) {
11557             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11558             return false;
11559         }
11560         int retCode = mInstaller.deleteCacheFiles(packageName, userId);
11561         if (retCode < 0) {
11562             Slog.w(TAG, "Couldn't remove cache files for package: "
11563                        + packageName + " u" + userId);
11564             return false;
11565         }
11566         return true;
11567     }
11568 
11569     @Override
getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)11570     public void getPackageSizeInfo(final String packageName, int userHandle,
11571             final IPackageStatsObserver observer) {
11572         mContext.enforceCallingOrSelfPermission(
11573                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
11574         if (packageName == null) {
11575             throw new IllegalArgumentException("Attempt to get size of null packageName");
11576         }
11577 
11578         PackageStats stats = new PackageStats(packageName, userHandle);
11579 
11580         /*
11581          * Queue up an async operation since the package measurement may take a
11582          * little while.
11583          */
11584         Message msg = mHandler.obtainMessage(INIT_COPY);
11585         msg.obj = new MeasureParams(stats, observer);
11586         mHandler.sendMessage(msg);
11587     }
11588 
getPackageSizeInfoLI(String packageName, int userHandle, PackageStats pStats)11589     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
11590             PackageStats pStats) {
11591         if (packageName == null) {
11592             Slog.w(TAG, "Attempt to get size of null packageName.");
11593             return false;
11594         }
11595         PackageParser.Package p;
11596         boolean dataOnly = false;
11597         String libDirRoot = null;
11598         String asecPath = null;
11599         PackageSetting ps = null;
11600         synchronized (mPackages) {
11601             p = mPackages.get(packageName);
11602             ps = mSettings.mPackages.get(packageName);
11603             if(p == null) {
11604                 dataOnly = true;
11605                 if((ps == null) || (ps.pkg == null)) {
11606                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11607                     return false;
11608                 }
11609                 p = ps.pkg;
11610             }
11611             if (ps != null) {
11612                 libDirRoot = ps.legacyNativeLibraryPathString;
11613             }
11614             if (p != null && (isExternal(p) || isForwardLocked(p))) {
11615                 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
11616                 if (secureContainerId != null) {
11617                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
11618                 }
11619             }
11620         }
11621         String publicSrcDir = null;
11622         if(!dataOnly) {
11623             final ApplicationInfo applicationInfo = p.applicationInfo;
11624             if (applicationInfo == null) {
11625                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11626                 return false;
11627             }
11628             if (isForwardLocked(p)) {
11629                 publicSrcDir = applicationInfo.getBaseResourcePath();
11630             }
11631         }
11632         // TODO: extend to measure size of split APKs
11633         // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
11634         // not just the first level.
11635         // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
11636         // just the primary.
11637         String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
11638         int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
11639                 publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
11640         if (res < 0) {
11641             return false;
11642         }
11643 
11644         // Fix-up for forward-locked applications in ASEC containers.
11645         if (!isExternal(p)) {
11646             pStats.codeSize += pStats.externalCodeSize;
11647             pStats.externalCodeSize = 0L;
11648         }
11649 
11650         return true;
11651     }
11652 
11653 
11654     @Override
addPackageToPreferred(String packageName)11655     public void addPackageToPreferred(String packageName) {
11656         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
11657     }
11658 
11659     @Override
removePackageFromPreferred(String packageName)11660     public void removePackageFromPreferred(String packageName) {
11661         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
11662     }
11663 
11664     @Override
getPreferredPackages(int flags)11665     public List<PackageInfo> getPreferredPackages(int flags) {
11666         return new ArrayList<PackageInfo>();
11667     }
11668 
getUidTargetSdkVersionLockedLPr(int uid)11669     private int getUidTargetSdkVersionLockedLPr(int uid) {
11670         Object obj = mSettings.getUserIdLPr(uid);
11671         if (obj instanceof SharedUserSetting) {
11672             final SharedUserSetting sus = (SharedUserSetting) obj;
11673             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
11674             final Iterator<PackageSetting> it = sus.packages.iterator();
11675             while (it.hasNext()) {
11676                 final PackageSetting ps = it.next();
11677                 if (ps.pkg != null) {
11678                     int v = ps.pkg.applicationInfo.targetSdkVersion;
11679                     if (v < vers) vers = v;
11680                 }
11681             }
11682             return vers;
11683         } else if (obj instanceof PackageSetting) {
11684             final PackageSetting ps = (PackageSetting) obj;
11685             if (ps.pkg != null) {
11686                 return ps.pkg.applicationInfo.targetSdkVersion;
11687             }
11688         }
11689         return Build.VERSION_CODES.CUR_DEVELOPMENT;
11690     }
11691 
11692     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)11693     public void addPreferredActivity(IntentFilter filter, int match,
11694             ComponentName[] set, ComponentName activity, int userId) {
11695         addPreferredActivityInternal(filter, match, set, activity, true, userId,
11696                 "Adding preferred");
11697     }
11698 
addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname)11699     private void addPreferredActivityInternal(IntentFilter filter, int match,
11700             ComponentName[] set, ComponentName activity, boolean always, int userId,
11701             String opname) {
11702         // writer
11703         int callingUid = Binder.getCallingUid();
11704         enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
11705         if (filter.countActions() == 0) {
11706             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11707             return;
11708         }
11709         synchronized (mPackages) {
11710             if (mContext.checkCallingOrSelfPermission(
11711                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11712                     != PackageManager.PERMISSION_GRANTED) {
11713                 if (getUidTargetSdkVersionLockedLPr(callingUid)
11714                         < Build.VERSION_CODES.FROYO) {
11715                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
11716                             + callingUid);
11717                     return;
11718                 }
11719                 mContext.enforceCallingOrSelfPermission(
11720                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11721             }
11722 
11723             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
11724             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
11725                     + userId + ":");
11726             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11727             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
11728             scheduleWritePackageRestrictionsLocked(userId);
11729         }
11730     }
11731 
11732     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)11733     public void replacePreferredActivity(IntentFilter filter, int match,
11734             ComponentName[] set, ComponentName activity, int userId) {
11735         if (filter.countActions() != 1) {
11736             throw new IllegalArgumentException(
11737                     "replacePreferredActivity expects filter to have only 1 action.");
11738         }
11739         if (filter.countDataAuthorities() != 0
11740                 || filter.countDataPaths() != 0
11741                 || filter.countDataSchemes() > 1
11742                 || filter.countDataTypes() != 0) {
11743             throw new IllegalArgumentException(
11744                     "replacePreferredActivity expects filter to have no data authorities, " +
11745                     "paths, or types; and at most one scheme.");
11746         }
11747 
11748         final int callingUid = Binder.getCallingUid();
11749         enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
11750         synchronized (mPackages) {
11751             if (mContext.checkCallingOrSelfPermission(
11752                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11753                     != PackageManager.PERMISSION_GRANTED) {
11754                 if (getUidTargetSdkVersionLockedLPr(callingUid)
11755                         < Build.VERSION_CODES.FROYO) {
11756                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
11757                             + Binder.getCallingUid());
11758                     return;
11759                 }
11760                 mContext.enforceCallingOrSelfPermission(
11761                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11762             }
11763 
11764             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11765             if (pir != null) {
11766                 // Get all of the existing entries that exactly match this filter.
11767                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
11768                 if (existing != null && existing.size() == 1) {
11769                     PreferredActivity cur = existing.get(0);
11770                     if (DEBUG_PREFERRED) {
11771                         Slog.i(TAG, "Checking replace of preferred:");
11772                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11773                         if (!cur.mPref.mAlways) {
11774                             Slog.i(TAG, "  -- CUR; not mAlways!");
11775                         } else {
11776                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
11777                             Slog.i(TAG, "  -- CUR: mSet="
11778                                     + Arrays.toString(cur.mPref.mSetComponents));
11779                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
11780                             Slog.i(TAG, "  -- NEW: mMatch="
11781                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
11782                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
11783                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
11784                         }
11785                     }
11786                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
11787                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
11788                             && cur.mPref.sameSet(set)) {
11789                         // Setting the preferred activity to what it happens to be already
11790                         if (DEBUG_PREFERRED) {
11791                             Slog.i(TAG, "Replacing with same preferred activity "
11792                                     + cur.mPref.mShortComponent + " for user "
11793                                     + userId + ":");
11794                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11795                         }
11796                         return;
11797                     }
11798                 }
11799 
11800                 if (existing != null) {
11801                     if (DEBUG_PREFERRED) {
11802                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
11803                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11804                     }
11805                     for (int i = 0; i < existing.size(); i++) {
11806                         PreferredActivity pa = existing.get(i);
11807                         if (DEBUG_PREFERRED) {
11808                             Slog.i(TAG, "Removing existing preferred activity "
11809                                     + pa.mPref.mComponent + ":");
11810                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
11811                         }
11812                         pir.removeFilter(pa);
11813                     }
11814                 }
11815             }
11816             addPreferredActivityInternal(filter, match, set, activity, true, userId,
11817                     "Replacing preferred");
11818         }
11819     }
11820 
11821     @Override
clearPackagePreferredActivities(String packageName)11822     public void clearPackagePreferredActivities(String packageName) {
11823         final int uid = Binder.getCallingUid();
11824         // writer
11825         synchronized (mPackages) {
11826             PackageParser.Package pkg = mPackages.get(packageName);
11827             if (pkg == null || pkg.applicationInfo.uid != uid) {
11828                 if (mContext.checkCallingOrSelfPermission(
11829                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11830                         != PackageManager.PERMISSION_GRANTED) {
11831                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
11832                             < Build.VERSION_CODES.FROYO) {
11833                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
11834                                 + Binder.getCallingUid());
11835                         return;
11836                     }
11837                     mContext.enforceCallingOrSelfPermission(
11838                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11839                 }
11840             }
11841 
11842             int user = UserHandle.getCallingUserId();
11843             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
11844                 scheduleWritePackageRestrictionsLocked(user);
11845             }
11846         }
11847     }
11848 
11849     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
clearPackagePreferredActivitiesLPw(String packageName, int userId)11850     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
11851         ArrayList<PreferredActivity> removed = null;
11852         boolean changed = false;
11853         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
11854             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
11855             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
11856             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
11857                 continue;
11858             }
11859             Iterator<PreferredActivity> it = pir.filterIterator();
11860             while (it.hasNext()) {
11861                 PreferredActivity pa = it.next();
11862                 // Mark entry for removal only if it matches the package name
11863                 // and the entry is of type "always".
11864                 if (packageName == null ||
11865                         (pa.mPref.mComponent.getPackageName().equals(packageName)
11866                                 && pa.mPref.mAlways)) {
11867                     if (removed == null) {
11868                         removed = new ArrayList<PreferredActivity>();
11869                     }
11870                     removed.add(pa);
11871                 }
11872             }
11873             if (removed != null) {
11874                 for (int j=0; j<removed.size(); j++) {
11875                     PreferredActivity pa = removed.get(j);
11876                     pir.removeFilter(pa);
11877                 }
11878                 changed = true;
11879             }
11880         }
11881         return changed;
11882     }
11883 
11884     @Override
resetPreferredActivities(int userId)11885     public void resetPreferredActivities(int userId) {
11886         /* TODO: Actually use userId. Why is it being passed in? */
11887         mContext.enforceCallingOrSelfPermission(
11888                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11889         // writer
11890         synchronized (mPackages) {
11891             int user = UserHandle.getCallingUserId();
11892             clearPackagePreferredActivitiesLPw(null, user);
11893             mSettings.readDefaultPreferredAppsLPw(this, user);
11894             scheduleWritePackageRestrictionsLocked(user);
11895         }
11896     }
11897 
11898     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)11899     public int getPreferredActivities(List<IntentFilter> outFilters,
11900             List<ComponentName> outActivities, String packageName) {
11901 
11902         int num = 0;
11903         final int userId = UserHandle.getCallingUserId();
11904         // reader
11905         synchronized (mPackages) {
11906             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11907             if (pir != null) {
11908                 final Iterator<PreferredActivity> it = pir.filterIterator();
11909                 while (it.hasNext()) {
11910                     final PreferredActivity pa = it.next();
11911                     if (packageName == null
11912                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
11913                                     && pa.mPref.mAlways)) {
11914                         if (outFilters != null) {
11915                             outFilters.add(new IntentFilter(pa));
11916                         }
11917                         if (outActivities != null) {
11918                             outActivities.add(pa.mPref.mComponent);
11919                         }
11920                     }
11921                 }
11922             }
11923         }
11924 
11925         return num;
11926     }
11927 
11928     @Override
addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)11929     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
11930             int userId) {
11931         int callingUid = Binder.getCallingUid();
11932         if (callingUid != Process.SYSTEM_UID) {
11933             throw new SecurityException(
11934                     "addPersistentPreferredActivity can only be run by the system");
11935         }
11936         if (filter.countActions() == 0) {
11937             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11938             return;
11939         }
11940         synchronized (mPackages) {
11941             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
11942                     " :");
11943             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11944             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
11945                     new PersistentPreferredActivity(filter, activity));
11946             scheduleWritePackageRestrictionsLocked(userId);
11947         }
11948     }
11949 
11950     @Override
clearPackagePersistentPreferredActivities(String packageName, int userId)11951     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
11952         int callingUid = Binder.getCallingUid();
11953         if (callingUid != Process.SYSTEM_UID) {
11954             throw new SecurityException(
11955                     "clearPackagePersistentPreferredActivities can only be run by the system");
11956         }
11957         ArrayList<PersistentPreferredActivity> removed = null;
11958         boolean changed = false;
11959         synchronized (mPackages) {
11960             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
11961                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
11962                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
11963                         .valueAt(i);
11964                 if (userId != thisUserId) {
11965                     continue;
11966                 }
11967                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
11968                 while (it.hasNext()) {
11969                     PersistentPreferredActivity ppa = it.next();
11970                     // Mark entry for removal only if it matches the package name.
11971                     if (ppa.mComponent.getPackageName().equals(packageName)) {
11972                         if (removed == null) {
11973                             removed = new ArrayList<PersistentPreferredActivity>();
11974                         }
11975                         removed.add(ppa);
11976                     }
11977                 }
11978                 if (removed != null) {
11979                     for (int j=0; j<removed.size(); j++) {
11980                         PersistentPreferredActivity ppa = removed.get(j);
11981                         ppir.removeFilter(ppa);
11982                     }
11983                     changed = true;
11984                 }
11985             }
11986 
11987             if (changed) {
11988                 scheduleWritePackageRestrictionsLocked(userId);
11989             }
11990         }
11991     }
11992 
11993     @Override
addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int ownerUserId, int sourceUserId, int targetUserId, int flags)11994     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
11995             int ownerUserId, int sourceUserId, int targetUserId, int flags) {
11996         mContext.enforceCallingOrSelfPermission(
11997                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11998         int callingUid = Binder.getCallingUid();
11999         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
12000         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
12001         if (intentFilter.countActions() == 0) {
12002             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
12003             return;
12004         }
12005         synchronized (mPackages) {
12006             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
12007                     ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
12008             CrossProfileIntentResolver resolver =
12009                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
12010             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
12011             // We have all those whose filter is equal. Now checking if the rest is equal as well.
12012             if (existing != null) {
12013                 int size = existing.size();
12014                 for (int i = 0; i < size; i++) {
12015                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
12016                         return;
12017                     }
12018                 }
12019             }
12020             resolver.addFilter(newFilter);
12021             scheduleWritePackageRestrictionsLocked(sourceUserId);
12022         }
12023     }
12024 
12025     @Override
clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, int ownerUserId)12026     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
12027             int ownerUserId) {
12028         mContext.enforceCallingOrSelfPermission(
12029                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
12030         int callingUid = Binder.getCallingUid();
12031         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
12032         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
12033         int callingUserId = UserHandle.getUserId(callingUid);
12034         synchronized (mPackages) {
12035             CrossProfileIntentResolver resolver =
12036                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
12037             ArraySet<CrossProfileIntentFilter> set =
12038                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
12039             for (CrossProfileIntentFilter filter : set) {
12040                 if (filter.getOwnerPackage().equals(ownerPackage)
12041                         && filter.getOwnerUserId() == callingUserId) {
12042                     resolver.removeFilter(filter);
12043                 }
12044             }
12045             scheduleWritePackageRestrictionsLocked(sourceUserId);
12046         }
12047     }
12048 
12049     // Enforcing that callingUid is owning pkg on userId
enforceOwnerRights(String pkg, int userId, int callingUid)12050     private void enforceOwnerRights(String pkg, int userId, int callingUid) {
12051         // The system owns everything.
12052         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
12053             return;
12054         }
12055         int callingUserId = UserHandle.getUserId(callingUid);
12056         if (callingUserId != userId) {
12057             throw new SecurityException("calling uid " + callingUid
12058                     + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
12059                     + callingUserId);
12060         }
12061         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
12062         if (pi == null) {
12063             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
12064                     + callingUserId);
12065         }
12066         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
12067             throw new SecurityException("Calling uid " + callingUid
12068                     + " does not own package " + pkg);
12069         }
12070     }
12071 
12072     @Override
getHomeActivities(List<ResolveInfo> allHomeCandidates)12073     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
12074         Intent intent = new Intent(Intent.ACTION_MAIN);
12075         intent.addCategory(Intent.CATEGORY_HOME);
12076 
12077         final int callingUserId = UserHandle.getCallingUserId();
12078         List<ResolveInfo> list = queryIntentActivities(intent, null,
12079                 PackageManager.GET_META_DATA, callingUserId);
12080         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
12081                 true, false, false, callingUserId);
12082 
12083         allHomeCandidates.clear();
12084         if (list != null) {
12085             for (ResolveInfo ri : list) {
12086                 allHomeCandidates.add(ri);
12087             }
12088         }
12089         return (preferred == null || preferred.activityInfo == null)
12090                 ? null
12091                 : new ComponentName(preferred.activityInfo.packageName,
12092                         preferred.activityInfo.name);
12093     }
12094 
12095     @Override
setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)12096     public void setApplicationEnabledSetting(String appPackageName,
12097             int newState, int flags, int userId, String callingPackage) {
12098         if (!sUserManager.exists(userId)) return;
12099         if (callingPackage == null) {
12100             callingPackage = Integer.toString(Binder.getCallingUid());
12101         }
12102         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
12103     }
12104 
12105     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)12106     public void setComponentEnabledSetting(ComponentName componentName,
12107             int newState, int flags, int userId) {
12108         if (!sUserManager.exists(userId)) return;
12109         setEnabledSetting(componentName.getPackageName(),
12110                 componentName.getClassName(), newState, flags, userId, null);
12111     }
12112 
setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)12113     private void setEnabledSetting(final String packageName, String className, int newState,
12114             final int flags, int userId, String callingPackage) {
12115         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
12116               || newState == COMPONENT_ENABLED_STATE_ENABLED
12117               || newState == COMPONENT_ENABLED_STATE_DISABLED
12118               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
12119               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
12120             throw new IllegalArgumentException("Invalid new component state: "
12121                     + newState);
12122         }
12123         PackageSetting pkgSetting;
12124         final int uid = Binder.getCallingUid();
12125         final int permission = mContext.checkCallingOrSelfPermission(
12126                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
12127         enforceCrossUserPermission(uid, userId, false, true, "set enabled");
12128         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
12129         boolean sendNow = false;
12130         boolean isApp = (className == null);
12131         String componentName = isApp ? packageName : className;
12132         int packageUid = -1;
12133         ArrayList<String> components;
12134 
12135         // writer
12136         synchronized (mPackages) {
12137             pkgSetting = mSettings.mPackages.get(packageName);
12138             if (pkgSetting == null) {
12139                 if (className == null) {
12140                     throw new IllegalArgumentException(
12141                             "Unknown package: " + packageName);
12142                 }
12143                 throw new IllegalArgumentException(
12144                         "Unknown component: " + packageName
12145                         + "/" + className);
12146             }
12147             // Allow root and verify that userId is not being specified by a different user
12148             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
12149                 throw new SecurityException(
12150                         "Permission Denial: attempt to change component state from pid="
12151                         + Binder.getCallingPid()
12152                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
12153             }
12154             if (className == null) {
12155                 // We're dealing with an application/package level state change
12156                 if (pkgSetting.getEnabled(userId) == newState) {
12157                     // Nothing to do
12158                     return;
12159                 }
12160                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
12161                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
12162                     // Don't care about who enables an app.
12163                     callingPackage = null;
12164                 }
12165                 pkgSetting.setEnabled(newState, userId, callingPackage);
12166                 // pkgSetting.pkg.mSetEnabled = newState;
12167             } else {
12168                 // We're dealing with a component level state change
12169                 // First, verify that this is a valid class name.
12170                 PackageParser.Package pkg = pkgSetting.pkg;
12171                 if (pkg == null || !pkg.hasComponentClassName(className)) {
12172                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
12173                         throw new IllegalArgumentException("Component class " + className
12174                                 + " does not exist in " + packageName);
12175                     } else {
12176                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
12177                                 + className + " does not exist in " + packageName);
12178                     }
12179                 }
12180                 switch (newState) {
12181                 case COMPONENT_ENABLED_STATE_ENABLED:
12182                     if (!pkgSetting.enableComponentLPw(className, userId)) {
12183                         return;
12184                     }
12185                     break;
12186                 case COMPONENT_ENABLED_STATE_DISABLED:
12187                     if (!pkgSetting.disableComponentLPw(className, userId)) {
12188                         return;
12189                     }
12190                     break;
12191                 case COMPONENT_ENABLED_STATE_DEFAULT:
12192                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
12193                         return;
12194                     }
12195                     break;
12196                 default:
12197                     Slog.e(TAG, "Invalid new component state: " + newState);
12198                     return;
12199                 }
12200             }
12201             mSettings.writePackageRestrictionsLPr(userId);
12202             components = mPendingBroadcasts.get(userId, packageName);
12203             final boolean newPackage = components == null;
12204             if (newPackage) {
12205                 components = new ArrayList<String>();
12206             }
12207             if (!components.contains(componentName)) {
12208                 components.add(componentName);
12209             }
12210             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
12211                 sendNow = true;
12212                 // Purge entry from pending broadcast list if another one exists already
12213                 // since we are sending one right away.
12214                 mPendingBroadcasts.remove(userId, packageName);
12215             } else {
12216                 if (newPackage) {
12217                     mPendingBroadcasts.put(userId, packageName, components);
12218                 }
12219                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
12220                     // Schedule a message
12221                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
12222                 }
12223             }
12224         }
12225 
12226         long callingId = Binder.clearCallingIdentity();
12227         try {
12228             if (sendNow) {
12229                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
12230                 sendPackageChangedBroadcast(packageName,
12231                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
12232             }
12233         } finally {
12234             Binder.restoreCallingIdentity(callingId);
12235         }
12236     }
12237 
sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)12238     private void sendPackageChangedBroadcast(String packageName,
12239             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
12240         if (DEBUG_INSTALL)
12241             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
12242                     + componentNames);
12243         Bundle extras = new Bundle(4);
12244         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
12245         String nameList[] = new String[componentNames.size()];
12246         componentNames.toArray(nameList);
12247         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
12248         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
12249         extras.putInt(Intent.EXTRA_UID, packageUid);
12250         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
12251                 new int[] {UserHandle.getUserId(packageUid)});
12252     }
12253 
12254     @Override
setPackageStoppedState(String packageName, boolean stopped, int userId)12255     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
12256         if (!sUserManager.exists(userId)) return;
12257         final int uid = Binder.getCallingUid();
12258         final int permission = mContext.checkCallingOrSelfPermission(
12259                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
12260         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
12261         enforceCrossUserPermission(uid, userId, true, true, "stop package");
12262         // writer
12263         synchronized (mPackages) {
12264             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
12265                     uid, userId)) {
12266                 scheduleWritePackageRestrictionsLocked(userId);
12267             }
12268         }
12269     }
12270 
12271     @Override
getInstallerPackageName(String packageName)12272     public String getInstallerPackageName(String packageName) {
12273         // reader
12274         synchronized (mPackages) {
12275             return mSettings.getInstallerPackageNameLPr(packageName);
12276         }
12277     }
12278 
12279     @Override
getApplicationEnabledSetting(String packageName, int userId)12280     public int getApplicationEnabledSetting(String packageName, int userId) {
12281         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12282         int uid = Binder.getCallingUid();
12283         enforceCrossUserPermission(uid, userId, false, false, "get enabled");
12284         // reader
12285         synchronized (mPackages) {
12286             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
12287         }
12288     }
12289 
12290     @Override
getComponentEnabledSetting(ComponentName componentName, int userId)12291     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
12292         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12293         int uid = Binder.getCallingUid();
12294         enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
12295         // reader
12296         synchronized (mPackages) {
12297             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
12298         }
12299     }
12300 
12301     @Override
enterSafeMode()12302     public void enterSafeMode() {
12303         enforceSystemOrRoot("Only the system can request entering safe mode");
12304 
12305         if (!mSystemReady) {
12306             mSafeMode = true;
12307         }
12308     }
12309 
12310     @Override
systemReady()12311     public void systemReady() {
12312         mSystemReady = true;
12313 
12314         // Read the compatibilty setting when the system is ready.
12315         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
12316                 mContext.getContentResolver(),
12317                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
12318         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
12319         if (DEBUG_SETTINGS) {
12320             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
12321         }
12322 
12323         synchronized (mPackages) {
12324             // Verify that all of the preferred activity components actually
12325             // exist.  It is possible for applications to be updated and at
12326             // that point remove a previously declared activity component that
12327             // had been set as a preferred activity.  We try to clean this up
12328             // the next time we encounter that preferred activity, but it is
12329             // possible for the user flow to never be able to return to that
12330             // situation so here we do a sanity check to make sure we haven't
12331             // left any junk around.
12332             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
12333             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12334                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12335                 removed.clear();
12336                 for (PreferredActivity pa : pir.filterSet()) {
12337                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
12338                         removed.add(pa);
12339                     }
12340                 }
12341                 if (removed.size() > 0) {
12342                     for (int r=0; r<removed.size(); r++) {
12343                         PreferredActivity pa = removed.get(r);
12344                         Slog.w(TAG, "Removing dangling preferred activity: "
12345                                 + pa.mPref.mComponent);
12346                         pir.removeFilter(pa);
12347                     }
12348                     mSettings.writePackageRestrictionsLPr(
12349                             mSettings.mPreferredActivities.keyAt(i));
12350                 }
12351             }
12352         }
12353         sUserManager.systemReady();
12354 
12355         // Kick off any messages waiting for system ready
12356         if (mPostSystemReadyMessages != null) {
12357             for (Message msg : mPostSystemReadyMessages) {
12358                 msg.sendToTarget();
12359             }
12360             mPostSystemReadyMessages = null;
12361         }
12362     }
12363 
12364     @Override
isSafeMode()12365     public boolean isSafeMode() {
12366         return mSafeMode;
12367     }
12368 
12369     @Override
hasSystemUidErrors()12370     public boolean hasSystemUidErrors() {
12371         return mHasSystemUidErrors;
12372     }
12373 
arrayToString(int[] array)12374     static String arrayToString(int[] array) {
12375         StringBuffer buf = new StringBuffer(128);
12376         buf.append('[');
12377         if (array != null) {
12378             for (int i=0; i<array.length; i++) {
12379                 if (i > 0) buf.append(", ");
12380                 buf.append(array[i]);
12381             }
12382         }
12383         buf.append(']');
12384         return buf.toString();
12385     }
12386 
12387     static class DumpState {
12388         public static final int DUMP_LIBS = 1 << 0;
12389         public static final int DUMP_FEATURES = 1 << 1;
12390         public static final int DUMP_RESOLVERS = 1 << 2;
12391         public static final int DUMP_PERMISSIONS = 1 << 3;
12392         public static final int DUMP_PACKAGES = 1 << 4;
12393         public static final int DUMP_SHARED_USERS = 1 << 5;
12394         public static final int DUMP_MESSAGES = 1 << 6;
12395         public static final int DUMP_PROVIDERS = 1 << 7;
12396         public static final int DUMP_VERIFIERS = 1 << 8;
12397         public static final int DUMP_PREFERRED = 1 << 9;
12398         public static final int DUMP_PREFERRED_XML = 1 << 10;
12399         public static final int DUMP_KEYSETS = 1 << 11;
12400         public static final int DUMP_VERSION = 1 << 12;
12401         public static final int DUMP_INSTALLS = 1 << 13;
12402 
12403         public static final int OPTION_SHOW_FILTERS = 1 << 0;
12404 
12405         private int mTypes;
12406 
12407         private int mOptions;
12408 
12409         private boolean mTitlePrinted;
12410 
12411         private SharedUserSetting mSharedUser;
12412 
isDumping(int type)12413         public boolean isDumping(int type) {
12414             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
12415                 return true;
12416             }
12417 
12418             return (mTypes & type) != 0;
12419         }
12420 
setDump(int type)12421         public void setDump(int type) {
12422             mTypes |= type;
12423         }
12424 
isOptionEnabled(int option)12425         public boolean isOptionEnabled(int option) {
12426             return (mOptions & option) != 0;
12427         }
12428 
setOptionEnabled(int option)12429         public void setOptionEnabled(int option) {
12430             mOptions |= option;
12431         }
12432 
onTitlePrinted()12433         public boolean onTitlePrinted() {
12434             final boolean printed = mTitlePrinted;
12435             mTitlePrinted = true;
12436             return printed;
12437         }
12438 
getTitlePrinted()12439         public boolean getTitlePrinted() {
12440             return mTitlePrinted;
12441         }
12442 
setTitlePrinted(boolean enabled)12443         public void setTitlePrinted(boolean enabled) {
12444             mTitlePrinted = enabled;
12445         }
12446 
getSharedUser()12447         public SharedUserSetting getSharedUser() {
12448             return mSharedUser;
12449         }
12450 
setSharedUser(SharedUserSetting user)12451         public void setSharedUser(SharedUserSetting user) {
12452             mSharedUser = user;
12453         }
12454     }
12455 
12456     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)12457     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12458         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
12459                 != PackageManager.PERMISSION_GRANTED) {
12460             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12461                     + Binder.getCallingPid()
12462                     + ", uid=" + Binder.getCallingUid()
12463                     + " without permission "
12464                     + android.Manifest.permission.DUMP);
12465             return;
12466         }
12467 
12468         DumpState dumpState = new DumpState();
12469         boolean fullPreferred = false;
12470         boolean checkin = false;
12471 
12472         String packageName = null;
12473 
12474         int opti = 0;
12475         while (opti < args.length) {
12476             String opt = args[opti];
12477             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12478                 break;
12479             }
12480             opti++;
12481 
12482             if ("-a".equals(opt)) {
12483                 // Right now we only know how to print all.
12484             } else if ("-h".equals(opt)) {
12485                 pw.println("Package manager dump options:");
12486                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
12487                 pw.println("    --checkin: dump for a checkin");
12488                 pw.println("    -f: print details of intent filters");
12489                 pw.println("    -h: print this help");
12490                 pw.println("  cmd may be one of:");
12491                 pw.println("    l[ibraries]: list known shared libraries");
12492                 pw.println("    f[ibraries]: list device features");
12493                 pw.println("    k[eysets]: print known keysets");
12494                 pw.println("    r[esolvers]: dump intent resolvers");
12495                 pw.println("    perm[issions]: dump permissions");
12496                 pw.println("    pref[erred]: print preferred package settings");
12497                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
12498                 pw.println("    prov[iders]: dump content providers");
12499                 pw.println("    p[ackages]: dump installed packages");
12500                 pw.println("    s[hared-users]: dump shared user IDs");
12501                 pw.println("    m[essages]: print collected runtime messages");
12502                 pw.println("    v[erifiers]: print package verifier info");
12503                 pw.println("    version: print database version info");
12504                 pw.println("    write: write current settings now");
12505                 pw.println("    <package.name>: info about given package");
12506                 pw.println("    installs: details about install sessions");
12507                 return;
12508             } else if ("--checkin".equals(opt)) {
12509                 checkin = true;
12510             } else if ("-f".equals(opt)) {
12511                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12512             } else {
12513                 pw.println("Unknown argument: " + opt + "; use -h for help");
12514             }
12515         }
12516 
12517         // Is the caller requesting to dump a particular piece of data?
12518         if (opti < args.length) {
12519             String cmd = args[opti];
12520             opti++;
12521             // Is this a package name?
12522             if ("android".equals(cmd) || cmd.contains(".")) {
12523                 packageName = cmd;
12524                 // When dumping a single package, we always dump all of its
12525                 // filter information since the amount of data will be reasonable.
12526                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12527             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
12528                 dumpState.setDump(DumpState.DUMP_LIBS);
12529             } else if ("f".equals(cmd) || "features".equals(cmd)) {
12530                 dumpState.setDump(DumpState.DUMP_FEATURES);
12531             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
12532                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
12533             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
12534                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
12535             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
12536                 dumpState.setDump(DumpState.DUMP_PREFERRED);
12537             } else if ("preferred-xml".equals(cmd)) {
12538                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
12539                 if (opti < args.length && "--full".equals(args[opti])) {
12540                     fullPreferred = true;
12541                     opti++;
12542                 }
12543             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
12544                 dumpState.setDump(DumpState.DUMP_PACKAGES);
12545             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
12546                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
12547             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
12548                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
12549             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
12550                 dumpState.setDump(DumpState.DUMP_MESSAGES);
12551             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
12552                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
12553             } else if ("version".equals(cmd)) {
12554                 dumpState.setDump(DumpState.DUMP_VERSION);
12555             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
12556                 dumpState.setDump(DumpState.DUMP_KEYSETS);
12557             } else if ("installs".equals(cmd)) {
12558                 dumpState.setDump(DumpState.DUMP_INSTALLS);
12559             } else if ("write".equals(cmd)) {
12560                 synchronized (mPackages) {
12561                     mSettings.writeLPr();
12562                     pw.println("Settings written.");
12563                     return;
12564                 }
12565             }
12566         }
12567 
12568         if (checkin) {
12569             pw.println("vers,1");
12570         }
12571 
12572         // reader
12573         synchronized (mPackages) {
12574             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
12575                 if (!checkin) {
12576                     if (dumpState.onTitlePrinted())
12577                         pw.println();
12578                     pw.println("Database versions:");
12579                     pw.print("  SDK Version:");
12580                     pw.print(" internal=");
12581                     pw.print(mSettings.mInternalSdkPlatform);
12582                     pw.print(" external=");
12583                     pw.println(mSettings.mExternalSdkPlatform);
12584                     pw.print("  DB Version:");
12585                     pw.print(" internal=");
12586                     pw.print(mSettings.mInternalDatabaseVersion);
12587                     pw.print(" external=");
12588                     pw.println(mSettings.mExternalDatabaseVersion);
12589                 }
12590             }
12591 
12592             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
12593                 if (!checkin) {
12594                     if (dumpState.onTitlePrinted())
12595                         pw.println();
12596                     pw.println("Verifiers:");
12597                     pw.print("  Required: ");
12598                     pw.print(mRequiredVerifierPackage);
12599                     pw.print(" (uid=");
12600                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
12601                     pw.println(")");
12602                 } else if (mRequiredVerifierPackage != null) {
12603                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
12604                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
12605                 }
12606             }
12607 
12608             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
12609                 boolean printedHeader = false;
12610                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
12611                 while (it.hasNext()) {
12612                     String name = it.next();
12613                     SharedLibraryEntry ent = mSharedLibraries.get(name);
12614                     if (!checkin) {
12615                         if (!printedHeader) {
12616                             if (dumpState.onTitlePrinted())
12617                                 pw.println();
12618                             pw.println("Libraries:");
12619                             printedHeader = true;
12620                         }
12621                         pw.print("  ");
12622                     } else {
12623                         pw.print("lib,");
12624                     }
12625                     pw.print(name);
12626                     if (!checkin) {
12627                         pw.print(" -> ");
12628                     }
12629                     if (ent.path != null) {
12630                         if (!checkin) {
12631                             pw.print("(jar) ");
12632                             pw.print(ent.path);
12633                         } else {
12634                             pw.print(",jar,");
12635                             pw.print(ent.path);
12636                         }
12637                     } else {
12638                         if (!checkin) {
12639                             pw.print("(apk) ");
12640                             pw.print(ent.apk);
12641                         } else {
12642                             pw.print(",apk,");
12643                             pw.print(ent.apk);
12644                         }
12645                     }
12646                     pw.println();
12647                 }
12648             }
12649 
12650             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
12651                 if (dumpState.onTitlePrinted())
12652                     pw.println();
12653                 if (!checkin) {
12654                     pw.println("Features:");
12655                 }
12656                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
12657                 while (it.hasNext()) {
12658                     String name = it.next();
12659                     if (!checkin) {
12660                         pw.print("  ");
12661                     } else {
12662                         pw.print("feat,");
12663                     }
12664                     pw.println(name);
12665                 }
12666             }
12667 
12668             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
12669                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
12670                         : "Activity Resolver Table:", "  ", packageName,
12671                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
12672                     dumpState.setTitlePrinted(true);
12673                 }
12674                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
12675                         : "Receiver Resolver Table:", "  ", packageName,
12676                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
12677                     dumpState.setTitlePrinted(true);
12678                 }
12679                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
12680                         : "Service Resolver Table:", "  ", packageName,
12681                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
12682                     dumpState.setTitlePrinted(true);
12683                 }
12684                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
12685                         : "Provider Resolver Table:", "  ", packageName,
12686                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
12687                     dumpState.setTitlePrinted(true);
12688                 }
12689             }
12690 
12691             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
12692                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12693                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12694                     int user = mSettings.mPreferredActivities.keyAt(i);
12695                     if (pir.dump(pw,
12696                             dumpState.getTitlePrinted()
12697                                 ? "\nPreferred Activities User " + user + ":"
12698                                 : "Preferred Activities User " + user + ":", "  ",
12699                             packageName, true, false)) {
12700                         dumpState.setTitlePrinted(true);
12701                     }
12702                 }
12703             }
12704 
12705             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
12706                 pw.flush();
12707                 FileOutputStream fout = new FileOutputStream(fd);
12708                 BufferedOutputStream str = new BufferedOutputStream(fout);
12709                 XmlSerializer serializer = new FastXmlSerializer();
12710                 try {
12711                     serializer.setOutput(str, "utf-8");
12712                     serializer.startDocument(null, true);
12713                     serializer.setFeature(
12714                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
12715                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
12716                     serializer.endDocument();
12717                     serializer.flush();
12718                 } catch (IllegalArgumentException e) {
12719                     pw.println("Failed writing: " + e);
12720                 } catch (IllegalStateException e) {
12721                     pw.println("Failed writing: " + e);
12722                 } catch (IOException e) {
12723                     pw.println("Failed writing: " + e);
12724                 }
12725             }
12726 
12727             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
12728                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
12729                 if (packageName == null) {
12730                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
12731                         if (iperm == 0) {
12732                             if (dumpState.onTitlePrinted())
12733                                 pw.println();
12734                             pw.println("AppOp Permissions:");
12735                         }
12736                         pw.print("  AppOp Permission ");
12737                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
12738                         pw.println(":");
12739                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
12740                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
12741                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
12742                         }
12743                     }
12744                 }
12745             }
12746 
12747             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
12748                 boolean printedSomething = false;
12749                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
12750                     if (packageName != null && !packageName.equals(p.info.packageName)) {
12751                         continue;
12752                     }
12753                     if (!printedSomething) {
12754                         if (dumpState.onTitlePrinted())
12755                             pw.println();
12756                         pw.println("Registered ContentProviders:");
12757                         printedSomething = true;
12758                     }
12759                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
12760                     pw.print("    "); pw.println(p.toString());
12761                 }
12762                 printedSomething = false;
12763                 for (Map.Entry<String, PackageParser.Provider> entry :
12764                         mProvidersByAuthority.entrySet()) {
12765                     PackageParser.Provider p = entry.getValue();
12766                     if (packageName != null && !packageName.equals(p.info.packageName)) {
12767                         continue;
12768                     }
12769                     if (!printedSomething) {
12770                         if (dumpState.onTitlePrinted())
12771                             pw.println();
12772                         pw.println("ContentProvider Authorities:");
12773                         printedSomething = true;
12774                     }
12775                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
12776                     pw.print("    "); pw.println(p.toString());
12777                     if (p.info != null && p.info.applicationInfo != null) {
12778                         final String appInfo = p.info.applicationInfo.toString();
12779                         pw.print("      applicationInfo="); pw.println(appInfo);
12780                     }
12781                 }
12782             }
12783 
12784             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
12785                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
12786             }
12787 
12788             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
12789                 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
12790             }
12791 
12792             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
12793                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
12794             }
12795 
12796             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
12797                 // XXX should handle packageName != null by dumping only install data that
12798                 // the given package is involved with.
12799                 if (dumpState.onTitlePrinted()) pw.println();
12800                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
12801             }
12802 
12803             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
12804                 if (dumpState.onTitlePrinted()) pw.println();
12805                 mSettings.dumpReadMessagesLPr(pw, dumpState);
12806 
12807                 pw.println();
12808                 pw.println("Package warning messages:");
12809                 BufferedReader in = null;
12810                 String line = null;
12811                 try {
12812                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
12813                     while ((line = in.readLine()) != null) {
12814                         if (line.contains("ignored: updated version")) continue;
12815                         pw.println(line);
12816                     }
12817                 } catch (IOException ignored) {
12818                 } finally {
12819                     IoUtils.closeQuietly(in);
12820                 }
12821             }
12822 
12823             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
12824                 BufferedReader in = null;
12825                 String line = null;
12826                 try {
12827                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
12828                     while ((line = in.readLine()) != null) {
12829                         if (line.contains("ignored: updated version")) continue;
12830                         pw.print("msg,");
12831                         pw.println(line);
12832                     }
12833                 } catch (IOException ignored) {
12834                 } finally {
12835                     IoUtils.closeQuietly(in);
12836                 }
12837             }
12838         }
12839     }
12840 
12841     // ------- apps on sdcard specific code -------
12842     static final boolean DEBUG_SD_INSTALL = false;
12843 
12844     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
12845 
12846     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
12847 
12848     private boolean mMediaMounted = false;
12849 
getEncryptKey()12850     static String getEncryptKey() {
12851         try {
12852             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
12853                     SD_ENCRYPTION_KEYSTORE_NAME);
12854             if (sdEncKey == null) {
12855                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
12856                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
12857                 if (sdEncKey == null) {
12858                     Slog.e(TAG, "Failed to create encryption keys");
12859                     return null;
12860                 }
12861             }
12862             return sdEncKey;
12863         } catch (NoSuchAlgorithmException nsae) {
12864             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
12865             return null;
12866         } catch (IOException ioe) {
12867             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
12868             return null;
12869         }
12870     }
12871 
12872     /*
12873      * Update media status on PackageManager.
12874      */
12875     @Override
updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)12876     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
12877         int callingUid = Binder.getCallingUid();
12878         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12879             throw new SecurityException("Media status can only be updated by the system");
12880         }
12881         // reader; this apparently protects mMediaMounted, but should probably
12882         // be a different lock in that case.
12883         synchronized (mPackages) {
12884             Log.i(TAG, "Updating external media status from "
12885                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
12886                     + (mediaStatus ? "mounted" : "unmounted"));
12887             if (DEBUG_SD_INSTALL)
12888                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
12889                         + ", mMediaMounted=" + mMediaMounted);
12890             if (mediaStatus == mMediaMounted) {
12891                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
12892                         : 0, -1);
12893                 mHandler.sendMessage(msg);
12894                 return;
12895             }
12896             mMediaMounted = mediaStatus;
12897         }
12898         // Queue up an async operation since the package installation may take a
12899         // little while.
12900         mHandler.post(new Runnable() {
12901             public void run() {
12902                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
12903             }
12904         });
12905     }
12906 
12907     /**
12908      * Called by MountService when the initial ASECs to scan are available.
12909      * Should block until all the ASEC containers are finished being scanned.
12910      */
scanAvailableAsecs()12911     public void scanAvailableAsecs() {
12912         updateExternalMediaStatusInner(true, false, false);
12913         if (mShouldRestoreconData) {
12914             SELinuxMMAC.setRestoreconDone();
12915             mShouldRestoreconData = false;
12916         }
12917     }
12918 
12919     /*
12920      * Collect information of applications on external media, map them against
12921      * existing containers and update information based on current mount status.
12922      * Please note that we always have to report status if reportStatus has been
12923      * set to true especially when unloading packages.
12924      */
updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)12925     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
12926             boolean externalStorage) {
12927         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
12928         int[] uidArr = EmptyArray.INT;
12929 
12930         final String[] list = PackageHelper.getSecureContainerList();
12931         if (ArrayUtils.isEmpty(list)) {
12932             Log.i(TAG, "No secure containers found");
12933         } else {
12934             // Process list of secure containers and categorize them
12935             // as active or stale based on their package internal state.
12936 
12937             // reader
12938             synchronized (mPackages) {
12939                 for (String cid : list) {
12940                     // Leave stages untouched for now; installer service owns them
12941                     if (PackageInstallerService.isStageName(cid)) continue;
12942 
12943                     if (DEBUG_SD_INSTALL)
12944                         Log.i(TAG, "Processing container " + cid);
12945                     String pkgName = getAsecPackageName(cid);
12946                     if (pkgName == null) {
12947                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
12948                         continue;
12949                     }
12950                     if (DEBUG_SD_INSTALL)
12951                         Log.i(TAG, "Looking for pkg : " + pkgName);
12952 
12953                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
12954                     if (ps == null) {
12955                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
12956                         continue;
12957                     }
12958 
12959                     /*
12960                      * Skip packages that are not external if we're unmounting
12961                      * external storage.
12962                      */
12963                     if (externalStorage && !isMounted && !isExternal(ps)) {
12964                         continue;
12965                     }
12966 
12967                     final AsecInstallArgs args = new AsecInstallArgs(cid,
12968                             getAppDexInstructionSets(ps), isForwardLocked(ps));
12969                     // The package status is changed only if the code path
12970                     // matches between settings and the container id.
12971                     if (ps.codePathString != null
12972                             && ps.codePathString.startsWith(args.getCodePath())) {
12973                         if (DEBUG_SD_INSTALL) {
12974                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
12975                                     + " at code path: " + ps.codePathString);
12976                         }
12977 
12978                         // We do have a valid package installed on sdcard
12979                         processCids.put(args, ps.codePathString);
12980                         final int uid = ps.appId;
12981                         if (uid != -1) {
12982                             uidArr = ArrayUtils.appendInt(uidArr, uid);
12983                         }
12984                     } else {
12985                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
12986                                 + ps.codePathString);
12987                     }
12988                 }
12989             }
12990 
12991             Arrays.sort(uidArr);
12992         }
12993 
12994         // Process packages with valid entries.
12995         if (isMounted) {
12996             if (DEBUG_SD_INSTALL)
12997                 Log.i(TAG, "Loading packages");
12998             loadMediaPackages(processCids, uidArr);
12999             startCleaningPackages();
13000             mInstallerService.onSecureContainersAvailable();
13001         } else {
13002             if (DEBUG_SD_INSTALL)
13003                 Log.i(TAG, "Unloading packages");
13004             unloadMediaPackages(processCids, uidArr, reportStatus);
13005         }
13006     }
13007 
sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)13008     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
13009             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
13010         int size = pkgList.size();
13011         if (size > 0) {
13012             // Send broadcasts here
13013             Bundle extras = new Bundle();
13014             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
13015                     .toArray(new String[size]));
13016             if (uidArr != null) {
13017                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
13018             }
13019             if (replacing) {
13020                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
13021             }
13022             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
13023                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
13024             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
13025         }
13026     }
13027 
13028    /*
13029      * Look at potentially valid container ids from processCids If package
13030      * information doesn't match the one on record or package scanning fails,
13031      * the cid is added to list of removeCids. We currently don't delete stale
13032      * containers.
13033      */
loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr)13034     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
13035         ArrayList<String> pkgList = new ArrayList<String>();
13036         Set<AsecInstallArgs> keys = processCids.keySet();
13037 
13038         for (AsecInstallArgs args : keys) {
13039             String codePath = processCids.get(args);
13040             if (DEBUG_SD_INSTALL)
13041                 Log.i(TAG, "Loading container : " + args.cid);
13042             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13043             try {
13044                 // Make sure there are no container errors first.
13045                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
13046                     Slog.e(TAG, "Failed to mount cid : " + args.cid
13047                             + " when installing from sdcard");
13048                     continue;
13049                 }
13050                 // Check code path here.
13051                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
13052                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
13053                             + " does not match one in settings " + codePath);
13054                     continue;
13055                 }
13056                 // Parse package
13057                 int parseFlags = mDefParseFlags;
13058                 if (args.isExternal()) {
13059                     parseFlags |= PackageParser.PARSE_ON_SDCARD;
13060                 }
13061                 if (args.isFwdLocked()) {
13062                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
13063                 }
13064 
13065                 synchronized (mInstallLock) {
13066                     PackageParser.Package pkg = null;
13067                     try {
13068                         pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
13069                     } catch (PackageManagerException e) {
13070                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
13071                     }
13072                     // Scan the package
13073                     if (pkg != null) {
13074                         /*
13075                          * TODO why is the lock being held? doPostInstall is
13076                          * called in other places without the lock. This needs
13077                          * to be straightened out.
13078                          */
13079                         // writer
13080                         synchronized (mPackages) {
13081                             retCode = PackageManager.INSTALL_SUCCEEDED;
13082                             pkgList.add(pkg.packageName);
13083                             // Post process args
13084                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
13085                                     pkg.applicationInfo.uid);
13086                         }
13087                     } else {
13088                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
13089                     }
13090                 }
13091 
13092             } finally {
13093                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
13094                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
13095                 }
13096             }
13097         }
13098         // writer
13099         synchronized (mPackages) {
13100             // If the platform SDK has changed since the last time we booted,
13101             // we need to re-grant app permission to catch any new ones that
13102             // appear. This is really a hack, and means that apps can in some
13103             // cases get permissions that the user didn't initially explicitly
13104             // allow... it would be nice to have some better way to handle
13105             // this situation.
13106             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
13107             if (regrantPermissions)
13108                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
13109                         + mSdkVersion + "; regranting permissions for external storage");
13110             mSettings.mExternalSdkPlatform = mSdkVersion;
13111 
13112             // Make sure group IDs have been assigned, and any permission
13113             // changes in other apps are accounted for
13114             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
13115                     | (regrantPermissions
13116                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
13117                             : 0));
13118 
13119             mSettings.updateExternalDatabaseVersion();
13120 
13121             // can downgrade to reader
13122             // Persist settings
13123             mSettings.writeLPr();
13124         }
13125         // Send a broadcast to let everyone know we are done processing
13126         if (pkgList.size() > 0) {
13127             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
13128         }
13129     }
13130 
13131    /*
13132      * Utility method to unload a list of specified containers
13133      */
unloadAllContainers(Set<AsecInstallArgs> cidArgs)13134     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
13135         // Just unmount all valid containers.
13136         for (AsecInstallArgs arg : cidArgs) {
13137             synchronized (mInstallLock) {
13138                 arg.doPostDeleteLI(false);
13139            }
13140        }
13141    }
13142 
13143     /*
13144      * Unload packages mounted on external media. This involves deleting package
13145      * data from internal structures, sending broadcasts about diabled packages,
13146      * gc'ing to free up references, unmounting all secure containers
13147      * corresponding to packages on external media, and posting a
13148      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
13149      * that we always have to post this message if status has been requested no
13150      * matter what.
13151      */
unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)13152     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
13153             final boolean reportStatus) {
13154         if (DEBUG_SD_INSTALL)
13155             Log.i(TAG, "unloading media packages");
13156         ArrayList<String> pkgList = new ArrayList<String>();
13157         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
13158         final Set<AsecInstallArgs> keys = processCids.keySet();
13159         for (AsecInstallArgs args : keys) {
13160             String pkgName = args.getPackageName();
13161             if (DEBUG_SD_INSTALL)
13162                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
13163             // Delete package internally
13164             PackageRemovedInfo outInfo = new PackageRemovedInfo();
13165             synchronized (mInstallLock) {
13166                 boolean res = deletePackageLI(pkgName, null, false, null, null,
13167                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
13168                 if (res) {
13169                     pkgList.add(pkgName);
13170                 } else {
13171                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
13172                     failedList.add(args);
13173                 }
13174             }
13175         }
13176 
13177         // reader
13178         synchronized (mPackages) {
13179             // We didn't update the settings after removing each package;
13180             // write them now for all packages.
13181             mSettings.writeLPr();
13182         }
13183 
13184         // We have to absolutely send UPDATED_MEDIA_STATUS only
13185         // after confirming that all the receivers processed the ordered
13186         // broadcast when packages get disabled, force a gc to clean things up.
13187         // and unload all the containers.
13188         if (pkgList.size() > 0) {
13189             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
13190                     new IIntentReceiver.Stub() {
13191                 public void performReceive(Intent intent, int resultCode, String data,
13192                         Bundle extras, boolean ordered, boolean sticky,
13193                         int sendingUser) throws RemoteException {
13194                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
13195                             reportStatus ? 1 : 0, 1, keys);
13196                     mHandler.sendMessage(msg);
13197                 }
13198             });
13199         } else {
13200             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
13201                     keys);
13202             mHandler.sendMessage(msg);
13203         }
13204     }
13205 
13206     /** Binder call */
13207     @Override
movePackage(final String packageName, final IPackageMoveObserver observer, final int flags)13208     public void movePackage(final String packageName, final IPackageMoveObserver observer,
13209             final int flags) {
13210         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
13211         UserHandle user = new UserHandle(UserHandle.getCallingUserId());
13212         int returnCode = PackageManager.MOVE_SUCCEEDED;
13213         int currInstallFlags = 0;
13214         int newInstallFlags = 0;
13215 
13216         File codeFile = null;
13217         String installerPackageName = null;
13218         String packageAbiOverride = null;
13219 
13220         // reader
13221         synchronized (mPackages) {
13222             final PackageParser.Package pkg = mPackages.get(packageName);
13223             final PackageSetting ps = mSettings.mPackages.get(packageName);
13224             if (pkg == null || ps == null) {
13225                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
13226             } else {
13227                 // Disable moving fwd locked apps and system packages
13228                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
13229                     Slog.w(TAG, "Cannot move system application");
13230                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
13231                 } else if (pkg.mOperationPending) {
13232                     Slog.w(TAG, "Attempt to move package which has pending operations");
13233                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
13234                 } else {
13235                     // Find install location first
13236                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13237                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
13238                         Slog.w(TAG, "Ambigous flags specified for move location.");
13239                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13240                     } else {
13241                         newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13242                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13243                         currInstallFlags = isExternal(pkg)
13244                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13245 
13246                         if (newInstallFlags == currInstallFlags) {
13247                             Slog.w(TAG, "No move required. Trying to move to same location");
13248                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13249                         } else {
13250                             if (isForwardLocked(pkg)) {
13251                                 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13252                                 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13253                             }
13254                         }
13255                     }
13256                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
13257                         pkg.mOperationPending = true;
13258                     }
13259                 }
13260 
13261                 codeFile = new File(pkg.codePath);
13262                 installerPackageName = ps.installerPackageName;
13263                 packageAbiOverride = ps.cpuAbiOverrideString;
13264             }
13265         }
13266 
13267         if (returnCode != PackageManager.MOVE_SUCCEEDED) {
13268             try {
13269                 observer.packageMoved(packageName, returnCode);
13270             } catch (RemoteException ignored) {
13271             }
13272             return;
13273         }
13274 
13275         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
13276             @Override
13277             public void onUserActionRequired(Intent intent) throws RemoteException {
13278                 throw new IllegalStateException();
13279             }
13280 
13281             @Override
13282             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
13283                     Bundle extras) throws RemoteException {
13284                 Slog.d(TAG, "Install result for move: "
13285                         + PackageManager.installStatusToString(returnCode, msg));
13286 
13287                 // We usually have a new package now after the install, but if
13288                 // we failed we need to clear the pending flag on the original
13289                 // package object.
13290                 synchronized (mPackages) {
13291                     final PackageParser.Package pkg = mPackages.get(packageName);
13292                     if (pkg != null) {
13293                         pkg.mOperationPending = false;
13294                     }
13295                 }
13296 
13297                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
13298                 switch (status) {
13299                     case PackageInstaller.STATUS_SUCCESS:
13300                         observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
13301                         break;
13302                     case PackageInstaller.STATUS_FAILURE_STORAGE:
13303                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
13304                         break;
13305                     default:
13306                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
13307                         break;
13308                 }
13309             }
13310         };
13311 
13312         // Treat a move like reinstalling an existing app, which ensures that we
13313         // process everythign uniformly, like unpacking native libraries.
13314         newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
13315 
13316         final Message msg = mHandler.obtainMessage(INIT_COPY);
13317         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
13318         msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
13319                 installerPackageName, null, user, packageAbiOverride);
13320         mHandler.sendMessage(msg);
13321     }
13322 
13323     @Override
setInstallLocation(int loc)13324     public boolean setInstallLocation(int loc) {
13325         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
13326                 null);
13327         if (getInstallLocation() == loc) {
13328             return true;
13329         }
13330         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
13331                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
13332             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
13333                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
13334             return true;
13335         }
13336         return false;
13337    }
13338 
13339     @Override
getInstallLocation()13340     public int getInstallLocation() {
13341         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13342                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
13343                 PackageHelper.APP_INSTALL_AUTO);
13344     }
13345 
13346     /** Called by UserManagerService */
cleanUpUserLILPw(UserManagerService userManager, int userHandle)13347     void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
13348         mDirtyUsers.remove(userHandle);
13349         mSettings.removeUserLPw(userHandle);
13350         mPendingBroadcasts.remove(userHandle);
13351         if (mInstaller != null) {
13352             // Technically, we shouldn't be doing this with the package lock
13353             // held.  However, this is very rare, and there is already so much
13354             // other disk I/O going on, that we'll let it slide for now.
13355             mInstaller.removeUserDataDirs(userHandle);
13356         }
13357         mUserNeedsBadging.delete(userHandle);
13358         removeUnusedPackagesLILPw(userManager, userHandle);
13359     }
13360 
13361     /**
13362      * We're removing userHandle and would like to remove any downloaded packages
13363      * that are no longer in use by any other user.
13364      * @param userHandle the user being removed
13365      */
removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle)13366     private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
13367         final boolean DEBUG_CLEAN_APKS = false;
13368         int [] users = userManager.getUserIdsLPr();
13369         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
13370         while (psit.hasNext()) {
13371             PackageSetting ps = psit.next();
13372             if (ps.pkg == null) {
13373                 continue;
13374             }
13375             final String packageName = ps.pkg.packageName;
13376             // Skip over if system app
13377             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13378                 continue;
13379             }
13380             if (DEBUG_CLEAN_APKS) {
13381                 Slog.i(TAG, "Checking package " + packageName);
13382             }
13383             boolean keep = false;
13384             for (int i = 0; i < users.length; i++) {
13385                 if (users[i] != userHandle && ps.getInstalled(users[i])) {
13386                     keep = true;
13387                     if (DEBUG_CLEAN_APKS) {
13388                         Slog.i(TAG, "  Keeping package " + packageName + " for user "
13389                                 + users[i]);
13390                     }
13391                     break;
13392                 }
13393             }
13394             if (!keep) {
13395                 if (DEBUG_CLEAN_APKS) {
13396                     Slog.i(TAG, "  Removing package " + packageName);
13397                 }
13398                 mHandler.post(new Runnable() {
13399                     public void run() {
13400                         deletePackageX(packageName, userHandle, 0);
13401                     } //end run
13402                 });
13403             }
13404         }
13405     }
13406 
13407     /** Called by UserManagerService */
createNewUserLILPw(int userHandle, File path)13408     void createNewUserLILPw(int userHandle, File path) {
13409         if (mInstaller != null) {
13410             mInstaller.createUserConfig(userHandle);
13411             mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
13412         }
13413     }
13414 
13415     @Override
getVerifierDeviceIdentity()13416     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
13417         mContext.enforceCallingOrSelfPermission(
13418                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13419                 "Only package verification agents can read the verifier device identity");
13420 
13421         synchronized (mPackages) {
13422             return mSettings.getVerifierDeviceIdentityLPw();
13423         }
13424     }
13425 
13426     @Override
setPermissionEnforced(String permission, boolean enforced)13427     public void setPermissionEnforced(String permission, boolean enforced) {
13428         mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
13429         if (READ_EXTERNAL_STORAGE.equals(permission)) {
13430             synchronized (mPackages) {
13431                 if (mSettings.mReadExternalStorageEnforced == null
13432                         || mSettings.mReadExternalStorageEnforced != enforced) {
13433                     mSettings.mReadExternalStorageEnforced = enforced;
13434                     mSettings.writeLPr();
13435                 }
13436             }
13437             // kill any non-foreground processes so we restart them and
13438             // grant/revoke the GID.
13439             final IActivityManager am = ActivityManagerNative.getDefault();
13440             if (am != null) {
13441                 final long token = Binder.clearCallingIdentity();
13442                 try {
13443                     am.killProcessesBelowForeground("setPermissionEnforcement");
13444                 } catch (RemoteException e) {
13445                 } finally {
13446                     Binder.restoreCallingIdentity(token);
13447                 }
13448             }
13449         } else {
13450             throw new IllegalArgumentException("No selective enforcement for " + permission);
13451         }
13452     }
13453 
13454     @Override
13455     @Deprecated
isPermissionEnforced(String permission)13456     public boolean isPermissionEnforced(String permission) {
13457         return true;
13458     }
13459 
13460     @Override
isStorageLow()13461     public boolean isStorageLow() {
13462         final long token = Binder.clearCallingIdentity();
13463         try {
13464             final DeviceStorageMonitorInternal
13465                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13466             if (dsm != null) {
13467                 return dsm.isMemoryLow();
13468             } else {
13469                 return false;
13470             }
13471         } finally {
13472             Binder.restoreCallingIdentity(token);
13473         }
13474     }
13475 
13476     @Override
getPackageInstaller()13477     public IPackageInstaller getPackageInstaller() {
13478         return mInstallerService;
13479     }
13480 
userNeedsBadging(int userId)13481     private boolean userNeedsBadging(int userId) {
13482         int index = mUserNeedsBadging.indexOfKey(userId);
13483         if (index < 0) {
13484             final UserInfo userInfo;
13485             final long token = Binder.clearCallingIdentity();
13486             try {
13487                 userInfo = sUserManager.getUserInfo(userId);
13488             } finally {
13489                 Binder.restoreCallingIdentity(token);
13490             }
13491             final boolean b;
13492             if (userInfo != null && userInfo.isManagedProfile()) {
13493                 b = true;
13494             } else {
13495                 b = false;
13496             }
13497             mUserNeedsBadging.put(userId, b);
13498             return b;
13499         }
13500         return mUserNeedsBadging.valueAt(index);
13501     }
13502 
13503     @Override
getKeySetByAlias(String packageName, String alias)13504     public KeySet getKeySetByAlias(String packageName, String alias) {
13505         if (packageName == null || alias == null) {
13506             return null;
13507         }
13508         synchronized(mPackages) {
13509             final PackageParser.Package pkg = mPackages.get(packageName);
13510             if (pkg == null) {
13511                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13512                 throw new IllegalArgumentException("Unknown package: " + packageName);
13513             }
13514             KeySetManagerService ksms = mSettings.mKeySetManagerService;
13515             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
13516         }
13517     }
13518 
13519     @Override
getSigningKeySet(String packageName)13520     public KeySet getSigningKeySet(String packageName) {
13521         if (packageName == null) {
13522             return null;
13523         }
13524         synchronized(mPackages) {
13525             final PackageParser.Package pkg = mPackages.get(packageName);
13526             if (pkg == null) {
13527                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13528                 throw new IllegalArgumentException("Unknown package: " + packageName);
13529             }
13530             if (pkg.applicationInfo.uid != Binder.getCallingUid()
13531                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
13532                 throw new SecurityException("May not access signing KeySet of other apps.");
13533             }
13534             KeySetManagerService ksms = mSettings.mKeySetManagerService;
13535             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
13536         }
13537     }
13538 
13539     @Override
isPackageSignedByKeySet(String packageName, KeySet ks)13540     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
13541         if (packageName == null || ks == null) {
13542             return false;
13543         }
13544         synchronized(mPackages) {
13545             final PackageParser.Package pkg = mPackages.get(packageName);
13546             if (pkg == null) {
13547                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13548                 throw new IllegalArgumentException("Unknown package: " + packageName);
13549             }
13550             IBinder ksh = ks.getToken();
13551             if (ksh instanceof KeySetHandle) {
13552                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13553                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
13554             }
13555             return false;
13556         }
13557     }
13558 
13559     @Override
isPackageSignedByKeySetExactly(String packageName, KeySet ks)13560     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
13561         if (packageName == null || ks == null) {
13562             return false;
13563         }
13564         synchronized(mPackages) {
13565             final PackageParser.Package pkg = mPackages.get(packageName);
13566             if (pkg == null) {
13567                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13568                 throw new IllegalArgumentException("Unknown package: " + packageName);
13569             }
13570             IBinder ksh = ks.getToken();
13571             if (ksh instanceof KeySetHandle) {
13572                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13573                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
13574             }
13575             return false;
13576         }
13577     }
13578 
getUsageStatsIfNoPackageUsageInfo()13579     public void getUsageStatsIfNoPackageUsageInfo() {
13580         if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
13581             UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
13582             if (usm == null) {
13583                 throw new IllegalStateException("UsageStatsManager must be initialized");
13584             }
13585             long now = System.currentTimeMillis();
13586             Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
13587             for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
13588                 String packageName = entry.getKey();
13589                 PackageParser.Package pkg = mPackages.get(packageName);
13590                 if (pkg == null) {
13591                     continue;
13592                 }
13593                 UsageStats usage = entry.getValue();
13594                 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
13595                 mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
13596             }
13597         }
13598     }
13599 
13600     /**
13601      * Check and throw if the given before/after packages would be considered a
13602      * downgrade.
13603      */
checkDowngrade(PackageParser.Package before, PackageInfoLite after)13604     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
13605             throws PackageManagerException {
13606         if (after.versionCode < before.mVersionCode) {
13607             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
13608                     "Update version code " + after.versionCode + " is older than current "
13609                     + before.mVersionCode);
13610         } else if (after.versionCode == before.mVersionCode) {
13611             if (after.baseRevisionCode < before.baseRevisionCode) {
13612                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
13613                         "Update base revision code " + after.baseRevisionCode
13614                         + " is older than current " + before.baseRevisionCode);
13615             }
13616 
13617             if (!ArrayUtils.isEmpty(after.splitNames)) {
13618                 for (int i = 0; i < after.splitNames.length; i++) {
13619                     final String splitName = after.splitNames[i];
13620                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
13621                     if (j != -1) {
13622                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
13623                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
13624                                     "Update split " + splitName + " revision code "
13625                                     + after.splitRevisionCodes[i] + " is older than current "
13626                                     + before.splitRevisionCodes[j]);
13627                         }
13628                     }
13629                 }
13630             }
13631         }
13632     }
13633 }
13634