OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID. am: 6f754e48e9 am: a0b119...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / pm / PackageManagerService.java
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.READ_EXTERNAL_STORAGE;
20 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
21 import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
27 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
28 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
29 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
30 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
31 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
33 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
34 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
35 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
36 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
37 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
38 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
39 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
52 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
53 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
54 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
55 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
56 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
57 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
58 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
59 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
60 import static android.content.pm.PackageManager.MATCH_ALL;
61 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
62 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
63 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
64 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
65 import static android.content.pm.PackageManager.PERMISSION_DENIED;
66 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
67 import static android.content.pm.PackageParser.isApkFile;
68 import static android.os.Process.PACKAGE_INFO_GID;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.system.OsConstants.O_CREAT;
71 import static android.system.OsConstants.O_RDWR;
72 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
73 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
74 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
75 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
76 import static com.android.internal.util.ArrayUtils.appendInt;
77 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
78 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
79 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
80 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
81 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
82 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
83 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
84 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
85
86 import android.Manifest;
87 import android.app.ActivityManager;
88 import android.app.ActivityManagerNative;
89 import android.app.AppGlobals;
90 import android.app.IActivityManager;
91 import android.app.admin.IDevicePolicyManager;
92 import android.app.backup.IBackupManager;
93 import android.app.usage.UsageStats;
94 import android.app.usage.UsageStatsManager;
95 import android.content.BroadcastReceiver;
96 import android.content.ComponentName;
97 import android.content.Context;
98 import android.content.IIntentReceiver;
99 import android.content.Intent;
100 import android.content.IntentFilter;
101 import android.content.IntentSender;
102 import android.content.IntentSender.SendIntentException;
103 import android.content.ServiceConnection;
104 import android.content.pm.ActivityInfo;
105 import android.content.pm.ApplicationInfo;
106 import android.content.pm.FeatureInfo;
107 import android.content.pm.IOnPermissionsChangeListener;
108 import android.content.pm.IPackageDataObserver;
109 import android.content.pm.IPackageDeleteObserver;
110 import android.content.pm.IPackageDeleteObserver2;
111 import android.content.pm.IPackageInstallObserver2;
112 import android.content.pm.IPackageInstaller;
113 import android.content.pm.IPackageManager;
114 import android.content.pm.IPackageMoveObserver;
115 import android.content.pm.IPackageStatsObserver;
116 import android.content.pm.InstrumentationInfo;
117 import android.content.pm.IntentFilterVerificationInfo;
118 import android.content.pm.KeySet;
119 import android.content.pm.ManifestDigest;
120 import android.content.pm.PackageCleanItem;
121 import android.content.pm.PackageInfo;
122 import android.content.pm.PackageInfoLite;
123 import android.content.pm.PackageInstaller;
124 import android.content.pm.PackageManager;
125 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
126 import android.content.pm.PackageManagerInternal;
127 import android.content.pm.PackageParser;
128 import android.content.pm.PackageParser.ActivityIntentInfo;
129 import android.content.pm.PackageParser.PackageLite;
130 import android.content.pm.PackageParser.PackageParserException;
131 import android.content.pm.PackageStats;
132 import android.content.pm.PackageUserState;
133 import android.content.pm.ParceledListSlice;
134 import android.content.pm.PermissionGroupInfo;
135 import android.content.pm.PermissionInfo;
136 import android.content.pm.ProviderInfo;
137 import android.content.pm.ResolveInfo;
138 import android.content.pm.ServiceInfo;
139 import android.content.pm.Signature;
140 import android.content.pm.UserInfo;
141 import android.content.pm.VerificationParams;
142 import android.content.pm.VerifierDeviceIdentity;
143 import android.content.pm.VerifierInfo;
144 import android.content.res.Resources;
145 import android.hardware.display.DisplayManager;
146 import android.net.Uri;
147 import android.os.Debug;
148 import android.os.Binder;
149 import android.os.Build;
150 import android.os.Bundle;
151 import android.os.Environment;
152 import android.os.Environment.UserEnvironment;
153 import android.os.FileUtils;
154 import android.os.Handler;
155 import android.os.IBinder;
156 import android.os.Looper;
157 import android.os.Message;
158 import android.os.Parcel;
159 import android.os.ParcelFileDescriptor;
160 import android.os.Process;
161 import android.os.RemoteCallbackList;
162 import android.os.RemoteException;
163 import android.os.SELinux;
164 import android.os.ServiceManager;
165 import android.os.SystemClock;
166 import android.os.SystemProperties;
167 import android.os.UserHandle;
168 import android.os.UserManager;
169 import android.os.storage.IMountService;
170 import android.os.storage.MountServiceInternal;
171 import android.os.storage.StorageEventListener;
172 import android.os.storage.StorageManager;
173 import android.os.storage.VolumeInfo;
174 import android.os.storage.VolumeRecord;
175 import android.security.KeyStore;
176 import android.security.SystemKeyStore;
177 import android.system.ErrnoException;
178 import android.system.Os;
179 import android.system.StructStat;
180 import android.text.TextUtils;
181 import android.text.format.DateUtils;
182 import android.util.ArrayMap;
183 import android.util.ArraySet;
184 import android.util.AtomicFile;
185 import android.util.DisplayMetrics;
186 import android.util.EventLog;
187 import android.util.ExceptionUtils;
188 import android.util.Log;
189 import android.util.LogPrinter;
190 import android.util.MathUtils;
191 import android.util.PrintStreamPrinter;
192 import android.util.Slog;
193 import android.util.SparseArray;
194 import android.util.SparseBooleanArray;
195 import android.util.SparseIntArray;
196 import android.util.Xml;
197 import android.view.Display;
198
199 import dalvik.system.DexFile;
200 import dalvik.system.VMRuntime;
201
202 import libcore.io.IoUtils;
203 import libcore.util.EmptyArray;
204
205 import com.android.internal.R;
206 import com.android.internal.annotations.GuardedBy;
207 import com.android.internal.app.IMediaContainerService;
208 import com.android.internal.app.ResolverActivity;
209 import com.android.internal.content.NativeLibraryHelper;
210 import com.android.internal.content.PackageHelper;
211 import com.android.internal.os.IParcelFileDescriptorFactory;
212 import com.android.internal.os.SomeArgs;
213 import com.android.internal.os.Zygote;
214 import com.android.internal.util.ArrayUtils;
215 import com.android.internal.util.FastPrintWriter;
216 import com.android.internal.util.FastXmlSerializer;
217 import com.android.internal.util.IndentingPrintWriter;
218 import com.android.internal.util.Preconditions;
219 import com.android.server.EventLogTags;
220 import com.android.server.FgThread;
221 import com.android.server.IntentResolver;
222 import com.android.server.LocalServices;
223 import com.android.server.ServiceThread;
224 import com.android.server.SystemConfig;
225 import com.android.server.Watchdog;
226 import com.android.server.pm.PermissionsState.PermissionState;
227 import com.android.server.pm.Settings.DatabaseVersion;
228 import com.android.server.pm.Settings.VersionInfo;
229 import com.android.server.storage.DeviceStorageMonitorInternal;
230
231 import org.xmlpull.v1.XmlPullParser;
232 import org.xmlpull.v1.XmlPullParserException;
233 import org.xmlpull.v1.XmlSerializer;
234
235 import java.io.BufferedInputStream;
236 import java.io.BufferedOutputStream;
237 import java.io.BufferedReader;
238 import java.io.ByteArrayInputStream;
239 import java.io.ByteArrayOutputStream;
240 import java.io.File;
241 import java.io.FileDescriptor;
242 import java.io.FileNotFoundException;
243 import java.io.FileOutputStream;
244 import java.io.FileReader;
245 import java.io.FilenameFilter;
246 import java.io.IOException;
247 import java.io.InputStream;
248 import java.io.PrintWriter;
249 import java.nio.charset.StandardCharsets;
250 import java.security.NoSuchAlgorithmException;
251 import java.security.PublicKey;
252 import java.security.cert.CertificateEncodingException;
253 import java.security.cert.CertificateException;
254 import java.text.SimpleDateFormat;
255 import java.util.ArrayList;
256 import java.util.Arrays;
257 import java.util.Collection;
258 import java.util.Collections;
259 import java.util.Comparator;
260 import java.util.Date;
261 import java.util.Iterator;
262 import java.util.List;
263 import java.util.Map;
264 import java.util.Objects;
265 import java.util.Set;
266 import java.util.concurrent.CountDownLatch;
267 import java.util.concurrent.TimeUnit;
268 import java.util.concurrent.atomic.AtomicBoolean;
269 import java.util.concurrent.atomic.AtomicInteger;
270 import java.util.concurrent.atomic.AtomicLong;
271
272 /**
273  * Keep track of all those .apks everywhere.
274  *
275  * This is very central to the platform's security; please run the unit
276  * tests whenever making modifications here:
277  *
278 mmm frameworks/base/tests/AndroidTests
279 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
280 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
281  *
282  * {@hide}
283  */
284 public class PackageManagerService extends IPackageManager.Stub {
285     static final String TAG = "PackageManager";
286     static final boolean DEBUG_SETTINGS = false;
287     static final boolean DEBUG_PREFERRED = false;
288     static final boolean DEBUG_UPGRADE = false;
289     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
290     private static final boolean DEBUG_BACKUP = false;
291     private static final boolean DEBUG_INSTALL = false;
292     private static final boolean DEBUG_REMOVE = false;
293     private static final boolean DEBUG_BROADCASTS = false;
294     private static final boolean DEBUG_SHOW_INFO = false;
295     private static final boolean DEBUG_PACKAGE_INFO = false;
296     private static final boolean DEBUG_INTENT_MATCHING = false;
297     private static final boolean DEBUG_PACKAGE_SCANNING = false;
298     private static final boolean DEBUG_VERIFY = false;
299     private static final boolean DEBUG_DEXOPT = false;
300     private static final boolean DEBUG_FILTERS = false;
301     private static final boolean DEBUG_ABI_SELECTION = false;
302
303     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
304
305     private static final int RADIO_UID = Process.PHONE_UID;
306     private static final int LOG_UID = Process.LOG_UID;
307     private static final int NFC_UID = Process.NFC_UID;
308     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
309     private static final int SHELL_UID = Process.SHELL_UID;
310
311     // Cap the size of permission trees that 3rd party apps can define
312     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
313
314     // Suffix used during package installation when copying/moving
315     // package apks to install directory.
316     private static final String INSTALL_PACKAGE_SUFFIX = "-";
317
318     static final int SCAN_NO_DEX = 1<<1;
319     static final int SCAN_FORCE_DEX = 1<<2;
320     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
321     static final int SCAN_NEW_INSTALL = 1<<4;
322     static final int SCAN_NO_PATHS = 1<<5;
323     static final int SCAN_UPDATE_TIME = 1<<6;
324     static final int SCAN_DEFER_DEX = 1<<7;
325     static final int SCAN_BOOTING = 1<<8;
326     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
327     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
328     static final int SCAN_REPLACING = 1<<11;
329     static final int SCAN_REQUIRE_KNOWN = 1<<12;
330     static final int SCAN_MOVE = 1<<13;
331     static final int SCAN_INITIAL = 1<<14;
332
333     static final int REMOVE_CHATTY = 1<<16;
334
335     private static final int[] EMPTY_INT_ARRAY = new int[0];
336
337     /**
338      * Timeout (in milliseconds) after which the watchdog should declare that
339      * our handler thread is wedged.  The usual default for such things is one
340      * minute but we sometimes do very lengthy I/O operations on this thread,
341      * such as installing multi-gigabyte applications, so ours needs to be longer.
342      */
343     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
344
345     /**
346      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
347      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
348      * settings entry if available, otherwise we use the hardcoded default.  If it's been
349      * more than this long since the last fstrim, we force one during the boot sequence.
350      *
351      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
352      * one gets run at the next available charging+idle time.  This final mandatory
353      * no-fstrim check kicks in only of the other scheduling criteria is never met.
354      */
355     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
356
357     /**
358      * Whether verification is enabled by default.
359      */
360     private static final boolean DEFAULT_VERIFY_ENABLE = true;
361
362     /**
363      * The default maximum time to wait for the verification agent to return in
364      * milliseconds.
365      */
366     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
367
368     /**
369      * The default response for package verification timeout.
370      *
371      * This can be either PackageManager.VERIFICATION_ALLOW or
372      * PackageManager.VERIFICATION_REJECT.
373      */
374     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
375
376     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
377
378     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
379             DEFAULT_CONTAINER_PACKAGE,
380             "com.android.defcontainer.DefaultContainerService");
381
382     private static final String KILL_APP_REASON_GIDS_CHANGED =
383             "permission grant or revoke changed gids";
384
385     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
386             "permissions revoked";
387
388     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
389
390     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
391
392     /** Permission grant: not grant the permission. */
393     private static final int GRANT_DENIED = 1;
394
395     /** Permission grant: grant the permission as an install permission. */
396     private static final int GRANT_INSTALL = 2;
397
398     /** Permission grant: grant the permission as an install permission for a legacy app. */
399     private static final int GRANT_INSTALL_LEGACY = 3;
400
401     /** Permission grant: grant the permission as a runtime one. */
402     private static final int GRANT_RUNTIME = 4;
403
404     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
405     private static final int GRANT_UPGRADE = 5;
406
407     /** Canonical intent used to identify what counts as a "web browser" app */
408     private static final Intent sBrowserIntent;
409     static {
410         sBrowserIntent = new Intent();
411         sBrowserIntent.setAction(Intent.ACTION_VIEW);
412         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
413         sBrowserIntent.setData(Uri.parse("http:"));
414     }
415
416     final ServiceThread mHandlerThread;
417
418     final PackageHandler mHandler;
419
420     /**
421      * Messages for {@link #mHandler} that need to wait for system ready before
422      * being dispatched.
423      */
424     private ArrayList<Message> mPostSystemReadyMessages;
425
426     final int mSdkVersion = Build.VERSION.SDK_INT;
427
428     final Context mContext;
429     final boolean mFactoryTest;
430     final boolean mOnlyCore;
431     final boolean mLazyDexOpt;
432     final long mDexOptLRUThresholdInMills;
433     final DisplayMetrics mMetrics;
434     final int mDefParseFlags;
435     final String[] mSeparateProcesses;
436     final boolean mIsUpgrade;
437
438     // This is where all application persistent data goes.
439     final File mAppDataDir;
440
441     // This is where all application persistent data goes for secondary users.
442     final File mUserAppDataDir;
443
444     /** The location for ASEC container files on internal storage. */
445     final String mAsecInternalPath;
446
447     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
448     // LOCK HELD.  Can be called with mInstallLock held.
449     @GuardedBy("mInstallLock")
450     final Installer mInstaller;
451
452     /** Directory where installed third-party apps stored */
453     final File mAppInstallDir;
454
455     /**
456      * Directory to which applications installed internally have their
457      * 32 bit native libraries copied.
458      */
459     private File mAppLib32InstallDir;
460
461     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
462     // apps.
463     final File mDrmAppPrivateInstallDir;
464
465     // ----------------------------------------------------------------
466
467     // Lock for state used when installing and doing other long running
468     // operations.  Methods that must be called with this lock held have
469     // the suffix "LI".
470     final Object mInstallLock = new Object();
471
472     // ----------------------------------------------------------------
473
474     // Keys are String (package name), values are Package.  This also serves
475     // as the lock for the global state.  Methods that must be called with
476     // this lock held have the prefix "LP".
477     @GuardedBy("mPackages")
478     final ArrayMap<String, PackageParser.Package> mPackages =
479             new ArrayMap<String, PackageParser.Package>();
480
481     // Tracks available target package names -> overlay package paths.
482     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
483         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
484
485     /**
486      * Tracks new system packages [received in an OTA] that we expect to
487      * find updated user-installed versions. Keys are package name, values
488      * are package location.
489      */
490     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
491
492     /**
493      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
494      */
495     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
496     /**
497      * Whether or not system app permissions should be promoted from install to runtime.
498      */
499     boolean mPromoteSystemApps;
500
501     final Settings mSettings;
502     boolean mRestoredSettings;
503
504     // System configuration read by SystemConfig.
505     final int[] mGlobalGids;
506     final SparseArray<ArraySet<String>> mSystemPermissions;
507     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
508
509     // If mac_permissions.xml was found for seinfo labeling.
510     boolean mFoundPolicyFile;
511
512     // If a recursive restorecon of /data/data/<pkg> is needed.
513     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
514
515     public static final class SharedLibraryEntry {
516         public final String path;
517         public final String apk;
518
519         SharedLibraryEntry(String _path, String _apk) {
520             path = _path;
521             apk = _apk;
522         }
523     }
524
525     // Currently known shared libraries.
526     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
527             new ArrayMap<String, SharedLibraryEntry>();
528
529     // All available activities, for your resolving pleasure.
530     final ActivityIntentResolver mActivities =
531             new ActivityIntentResolver();
532
533     // All available receivers, for your resolving pleasure.
534     final ActivityIntentResolver mReceivers =
535             new ActivityIntentResolver();
536
537     // All available services, for your resolving pleasure.
538     final ServiceIntentResolver mServices = new ServiceIntentResolver();
539
540     // All available providers, for your resolving pleasure.
541     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
542
543     // Mapping from provider base names (first directory in content URI codePath)
544     // to the provider information.
545     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
546             new ArrayMap<String, PackageParser.Provider>();
547
548     // Mapping from instrumentation class names to info about them.
549     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
550             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
551
552     // Mapping from permission names to info about them.
553     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
554             new ArrayMap<String, PackageParser.PermissionGroup>();
555
556     // Packages whose data we have transfered into another package, thus
557     // should no longer exist.
558     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
559
560     // Broadcast actions that are only available to the system.
561     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
562
563     /** List of packages waiting for verification. */
564     final SparseArray<PackageVerificationState> mPendingVerification
565             = new SparseArray<PackageVerificationState>();
566
567     /** Set of packages associated with each app op permission. */
568     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
569
570     final PackageInstallerService mInstallerService;
571
572     private final PackageDexOptimizer mPackageDexOptimizer;
573
574     private AtomicInteger mNextMoveId = new AtomicInteger();
575     private final MoveCallbacks mMoveCallbacks;
576
577     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
578
579     // Cache of users who need badging.
580     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
581
582     /** Token for keys in mPendingVerification. */
583     private int mPendingVerificationToken = 0;
584
585     volatile boolean mSystemReady;
586     volatile boolean mSafeMode;
587     volatile boolean mHasSystemUidErrors;
588
589     ApplicationInfo mAndroidApplication;
590     final ActivityInfo mResolveActivity = new ActivityInfo();
591     final ResolveInfo mResolveInfo = new ResolveInfo();
592     ComponentName mResolveComponentName;
593     PackageParser.Package mPlatformPackage;
594     ComponentName mCustomResolverComponentName;
595
596     boolean mResolverReplaced = false;
597
598     private final ComponentName mIntentFilterVerifierComponent;
599     private int mIntentFilterVerificationToken = 0;
600
601     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
602             = new SparseArray<IntentFilterVerificationState>();
603
604     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
605             new DefaultPermissionGrantPolicy(this);
606
607     private static class IFVerificationParams {
608         PackageParser.Package pkg;
609         boolean replacing;
610         int userId;
611         int verifierUid;
612
613         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
614                 int _userId, int _verifierUid) {
615             pkg = _pkg;
616             replacing = _replacing;
617             userId = _userId;
618             replacing = _replacing;
619             verifierUid = _verifierUid;
620         }
621     }
622
623     private interface IntentFilterVerifier<T extends IntentFilter> {
624         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
625                                                T filter, String packageName);
626         void startVerifications(int userId);
627         void receiveVerificationResponse(int verificationId);
628     }
629
630     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
631         private Context mContext;
632         private ComponentName mIntentFilterVerifierComponent;
633         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
634
635         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
636             mContext = context;
637             mIntentFilterVerifierComponent = verifierComponent;
638         }
639
640         private String getDefaultScheme() {
641             return IntentFilter.SCHEME_HTTPS;
642         }
643
644         @Override
645         public void startVerifications(int userId) {
646             // Launch verifications requests
647             int count = mCurrentIntentFilterVerifications.size();
648             for (int n=0; n<count; n++) {
649                 int verificationId = mCurrentIntentFilterVerifications.get(n);
650                 final IntentFilterVerificationState ivs =
651                         mIntentFilterVerificationStates.get(verificationId);
652
653                 String packageName = ivs.getPackageName();
654
655                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
656                 final int filterCount = filters.size();
657                 ArraySet<String> domainsSet = new ArraySet<>();
658                 for (int m=0; m<filterCount; m++) {
659                     PackageParser.ActivityIntentInfo filter = filters.get(m);
660                     domainsSet.addAll(filter.getHostsList());
661                 }
662                 ArrayList<String> domainsList = new ArrayList<>(domainsSet);
663                 synchronized (mPackages) {
664                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
665                             packageName, domainsList) != null) {
666                         scheduleWriteSettingsLocked();
667                     }
668                 }
669                 sendVerificationRequest(userId, verificationId, ivs);
670             }
671             mCurrentIntentFilterVerifications.clear();
672         }
673
674         private void sendVerificationRequest(int userId, int verificationId,
675                 IntentFilterVerificationState ivs) {
676
677             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
678             verificationIntent.putExtra(
679                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
680                     verificationId);
681             verificationIntent.putExtra(
682                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
683                     getDefaultScheme());
684             verificationIntent.putExtra(
685                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
686                     ivs.getHostsString());
687             verificationIntent.putExtra(
688                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
689                     ivs.getPackageName());
690             verificationIntent.setComponent(mIntentFilterVerifierComponent);
691             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
692
693             UserHandle user = new UserHandle(userId);
694             mContext.sendBroadcastAsUser(verificationIntent, user);
695             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
696                     "Sending IntentFilter verification broadcast");
697         }
698
699         public void receiveVerificationResponse(int verificationId) {
700             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
701
702             final boolean verified = ivs.isVerified();
703
704             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
705             final int count = filters.size();
706             if (DEBUG_DOMAIN_VERIFICATION) {
707                 Slog.i(TAG, "Received verification response " + verificationId
708                         + " for " + count + " filters, verified=" + verified);
709             }
710             for (int n=0; n<count; n++) {
711                 PackageParser.ActivityIntentInfo filter = filters.get(n);
712                 filter.setVerified(verified);
713
714                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
715                         + " verified with result:" + verified + " and hosts:"
716                         + ivs.getHostsString());
717             }
718
719             mIntentFilterVerificationStates.remove(verificationId);
720
721             final String packageName = ivs.getPackageName();
722             IntentFilterVerificationInfo ivi = null;
723
724             synchronized (mPackages) {
725                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
726             }
727             if (ivi == null) {
728                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
729                         + verificationId + " packageName:" + packageName);
730                 return;
731             }
732             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
733                     "Updating IntentFilterVerificationInfo for package " + packageName
734                             +" verificationId:" + verificationId);
735
736             synchronized (mPackages) {
737                 if (verified) {
738                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
739                 } else {
740                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
741                 }
742                 scheduleWriteSettingsLocked();
743
744                 final int userId = ivs.getUserId();
745                 if (userId != UserHandle.USER_ALL) {
746                     final int userStatus =
747                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
748
749                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
750                     boolean needUpdate = false;
751
752                     // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
753                     // already been set by the User thru the Disambiguation dialog
754                     switch (userStatus) {
755                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
756                             if (verified) {
757                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
758                             } else {
759                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
760                             }
761                             needUpdate = true;
762                             break;
763
764                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
765                             if (verified) {
766                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
767                                 needUpdate = true;
768                             }
769                             break;
770
771                         default:
772                             // Nothing to do
773                     }
774
775                     if (needUpdate) {
776                         mSettings.updateIntentFilterVerificationStatusLPw(
777                                 packageName, updatedStatus, userId);
778                         scheduleWritePackageRestrictionsLocked(userId);
779                     }
780                 }
781             }
782         }
783
784         @Override
785         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
786                     ActivityIntentInfo filter, String packageName) {
787             if (!hasValidDomains(filter)) {
788                 return false;
789             }
790             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
791             if (ivs == null) {
792                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
793                         packageName);
794             }
795             if (DEBUG_DOMAIN_VERIFICATION) {
796                 Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter);
797             }
798             ivs.addFilter(filter);
799             return true;
800         }
801
802         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
803                 int userId, int verificationId, String packageName) {
804             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
805                     verifierUid, userId, packageName);
806             ivs.setPendingState();
807             synchronized (mPackages) {
808                 mIntentFilterVerificationStates.append(verificationId, ivs);
809                 mCurrentIntentFilterVerifications.add(verificationId);
810             }
811             return ivs;
812         }
813     }
814
815     private static boolean hasValidDomains(ActivityIntentInfo filter) {
816         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
817                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
818                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
819     }
820
821     private IntentFilterVerifier mIntentFilterVerifier;
822
823     // Set of pending broadcasts for aggregating enable/disable of components.
824     static class PendingPackageBroadcasts {
825         // for each user id, a map of <package name -> components within that package>
826         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
827
828         public PendingPackageBroadcasts() {
829             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
830         }
831
832         public ArrayList<String> get(int userId, String packageName) {
833             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
834             return packages.get(packageName);
835         }
836
837         public void put(int userId, String packageName, ArrayList<String> components) {
838             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
839             packages.put(packageName, components);
840         }
841
842         public void remove(int userId, String packageName) {
843             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
844             if (packages != null) {
845                 packages.remove(packageName);
846             }
847         }
848
849         public void remove(int userId) {
850             mUidMap.remove(userId);
851         }
852
853         public int userIdCount() {
854             return mUidMap.size();
855         }
856
857         public int userIdAt(int n) {
858             return mUidMap.keyAt(n);
859         }
860
861         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
862             return mUidMap.get(userId);
863         }
864
865         public int size() {
866             // total number of pending broadcast entries across all userIds
867             int num = 0;
868             for (int i = 0; i< mUidMap.size(); i++) {
869                 num += mUidMap.valueAt(i).size();
870             }
871             return num;
872         }
873
874         public void clear() {
875             mUidMap.clear();
876         }
877
878         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
879             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
880             if (map == null) {
881                 map = new ArrayMap<String, ArrayList<String>>();
882                 mUidMap.put(userId, map);
883             }
884             return map;
885         }
886     }
887     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
888
889     // Service Connection to remote media container service to copy
890     // package uri's from external media onto secure containers
891     // or internal storage.
892     private IMediaContainerService mContainerService = null;
893
894     static final int SEND_PENDING_BROADCAST = 1;
895     static final int MCS_BOUND = 3;
896     static final int END_COPY = 4;
897     static final int INIT_COPY = 5;
898     static final int MCS_UNBIND = 6;
899     static final int START_CLEANING_PACKAGE = 7;
900     static final int FIND_INSTALL_LOC = 8;
901     static final int POST_INSTALL = 9;
902     static final int MCS_RECONNECT = 10;
903     static final int MCS_GIVE_UP = 11;
904     static final int UPDATED_MEDIA_STATUS = 12;
905     static final int WRITE_SETTINGS = 13;
906     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
907     static final int PACKAGE_VERIFIED = 15;
908     static final int CHECK_PENDING_VERIFICATION = 16;
909     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
910     static final int INTENT_FILTER_VERIFIED = 18;
911
912     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
913
914     // Delay time in millisecs
915     static final int BROADCAST_DELAY = 10 * 1000;
916
917     static UserManagerService sUserManager;
918
919     // Stores a list of users whose package restrictions file needs to be updated
920     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
921
922     final private DefaultContainerConnection mDefContainerConn =
923             new DefaultContainerConnection();
924     class DefaultContainerConnection implements ServiceConnection {
925         public void onServiceConnected(ComponentName name, IBinder service) {
926             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
927             IMediaContainerService imcs =
928                 IMediaContainerService.Stub.asInterface(service);
929             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
930         }
931
932         public void onServiceDisconnected(ComponentName name) {
933             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
934         }
935     }
936
937     // Recordkeeping of restore-after-install operations that are currently in flight
938     // between the Package Manager and the Backup Manager
939     class PostInstallData {
940         public InstallArgs args;
941         public PackageInstalledInfo res;
942
943         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
944             args = _a;
945             res = _r;
946         }
947     }
948
949     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
950     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
951
952     // XML tags for backup/restore of various bits of state
953     private static final String TAG_PREFERRED_BACKUP = "pa";
954     private static final String TAG_DEFAULT_APPS = "da";
955     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
956
957     final String mRequiredVerifierPackage;
958     final String mRequiredInstallerPackage;
959
960     private final PackageUsage mPackageUsage = new PackageUsage();
961
962     private class PackageUsage {
963         private static final int WRITE_INTERVAL
964             = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
965
966         private final Object mFileLock = new Object();
967         private final AtomicLong mLastWritten = new AtomicLong(0);
968         private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
969
970         private boolean mIsHistoricalPackageUsageAvailable = true;
971
972         boolean isHistoricalPackageUsageAvailable() {
973             return mIsHistoricalPackageUsageAvailable;
974         }
975
976         void write(boolean force) {
977             if (force) {
978                 writeInternal();
979                 return;
980             }
981             if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
982                 && !DEBUG_DEXOPT) {
983                 return;
984             }
985             if (mBackgroundWriteRunning.compareAndSet(false, true)) {
986                 new Thread("PackageUsage_DiskWriter") {
987                     @Override
988                     public void run() {
989                         try {
990                             writeInternal();
991                         } finally {
992                             mBackgroundWriteRunning.set(false);
993                         }
994                     }
995                 }.start();
996             }
997         }
998
999         private void writeInternal() {
1000             synchronized (mPackages) {
1001                 synchronized (mFileLock) {
1002                     AtomicFile file = getFile();
1003                     FileOutputStream f = null;
1004                     try {
1005                         f = file.startWrite();
1006                         BufferedOutputStream out = new BufferedOutputStream(f);
1007                         FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
1008                         StringBuilder sb = new StringBuilder();
1009                         for (PackageParser.Package pkg : mPackages.values()) {
1010                             if (pkg.mLastPackageUsageTimeInMills == 0) {
1011                                 continue;
1012                             }
1013                             sb.setLength(0);
1014                             sb.append(pkg.packageName);
1015                             sb.append(' ');
1016                             sb.append((long)pkg.mLastPackageUsageTimeInMills);
1017                             sb.append('\n');
1018                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
1019                         }
1020                         out.flush();
1021                         file.finishWrite(f);
1022                     } catch (IOException e) {
1023                         if (f != null) {
1024                             file.failWrite(f);
1025                         }
1026                         Log.e(TAG, "Failed to write package usage times", e);
1027                     }
1028                 }
1029             }
1030             mLastWritten.set(SystemClock.elapsedRealtime());
1031         }
1032
1033         void readLP() {
1034             synchronized (mFileLock) {
1035                 AtomicFile file = getFile();
1036                 BufferedInputStream in = null;
1037                 try {
1038                     in = new BufferedInputStream(file.openRead());
1039                     StringBuffer sb = new StringBuffer();
1040                     while (true) {
1041                         String packageName = readToken(in, sb, ' ');
1042                         if (packageName == null) {
1043                             break;
1044                         }
1045                         String timeInMillisString = readToken(in, sb, '\n');
1046                         if (timeInMillisString == null) {
1047                             throw new IOException("Failed to find last usage time for package "
1048                                                   + packageName);
1049                         }
1050                         PackageParser.Package pkg = mPackages.get(packageName);
1051                         if (pkg == null) {
1052                             continue;
1053                         }
1054                         long timeInMillis;
1055                         try {
1056                             timeInMillis = Long.parseLong(timeInMillisString.toString());
1057                         } catch (NumberFormatException e) {
1058                             throw new IOException("Failed to parse " + timeInMillisString
1059                                                   + " as a long.", e);
1060                         }
1061                         pkg.mLastPackageUsageTimeInMills = timeInMillis;
1062                     }
1063                 } catch (FileNotFoundException expected) {
1064                     mIsHistoricalPackageUsageAvailable = false;
1065                 } catch (IOException e) {
1066                     Log.w(TAG, "Failed to read package usage times", e);
1067                 } finally {
1068                     IoUtils.closeQuietly(in);
1069                 }
1070             }
1071             mLastWritten.set(SystemClock.elapsedRealtime());
1072         }
1073
1074         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
1075                 throws IOException {
1076             sb.setLength(0);
1077             while (true) {
1078                 int ch = in.read();
1079                 if (ch == -1) {
1080                     if (sb.length() == 0) {
1081                         return null;
1082                     }
1083                     throw new IOException("Unexpected EOF");
1084                 }
1085                 if (ch == endOfToken) {
1086                     return sb.toString();
1087                 }
1088                 sb.append((char)ch);
1089             }
1090         }
1091
1092         private AtomicFile getFile() {
1093             File dataDir = Environment.getDataDirectory();
1094             File systemDir = new File(dataDir, "system");
1095             File fname = new File(systemDir, "package-usage.list");
1096             return new AtomicFile(fname);
1097         }
1098     }
1099
1100     class PackageHandler extends Handler {
1101         private boolean mBound = false;
1102         final ArrayList<HandlerParams> mPendingInstalls =
1103             new ArrayList<HandlerParams>();
1104
1105         private boolean connectToService() {
1106             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1107                     " DefaultContainerService");
1108             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1109             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1110             if (mContext.bindServiceAsUser(service, mDefContainerConn,
1111                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
1112                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1113                 mBound = true;
1114                 return true;
1115             }
1116             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1117             return false;
1118         }
1119
1120         private void disconnectService() {
1121             mContainerService = null;
1122             mBound = false;
1123             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1124             mContext.unbindService(mDefContainerConn);
1125             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1126         }
1127
1128         PackageHandler(Looper looper) {
1129             super(looper);
1130         }
1131
1132         public void handleMessage(Message msg) {
1133             try {
1134                 doHandleMessage(msg);
1135             } finally {
1136                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1137             }
1138         }
1139
1140         void doHandleMessage(Message msg) {
1141             switch (msg.what) {
1142                 case INIT_COPY: {
1143                     HandlerParams params = (HandlerParams) msg.obj;
1144                     int idx = mPendingInstalls.size();
1145                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1146                     // If a bind was already initiated we dont really
1147                     // need to do anything. The pending install
1148                     // will be processed later on.
1149                     if (!mBound) {
1150                         // If this is the only one pending we might
1151                         // have to bind to the service again.
1152                         if (!connectToService()) {
1153                             Slog.e(TAG, "Failed to bind to media container service");
1154                             params.serviceError();
1155                             return;
1156                         } else {
1157                             // Once we bind to the service, the first
1158                             // pending request will be processed.
1159                             mPendingInstalls.add(idx, params);
1160                         }
1161                     } else {
1162                         mPendingInstalls.add(idx, params);
1163                         // Already bound to the service. Just make
1164                         // sure we trigger off processing the first request.
1165                         if (idx == 0) {
1166                             mHandler.sendEmptyMessage(MCS_BOUND);
1167                         }
1168                     }
1169                     break;
1170                 }
1171                 case MCS_BOUND: {
1172                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1173                     if (msg.obj != null) {
1174                         mContainerService = (IMediaContainerService) msg.obj;
1175                     }
1176                     if (mContainerService == null) {
1177                         if (!mBound) {
1178                             // Something seriously wrong since we are not bound and we are not
1179                             // waiting for connection. Bail out.
1180                             Slog.e(TAG, "Cannot bind to media container service");
1181                             for (HandlerParams params : mPendingInstalls) {
1182                                 // Indicate service bind error
1183                                 params.serviceError();
1184                             }
1185                             mPendingInstalls.clear();
1186                         } else {
1187                             Slog.w(TAG, "Waiting to connect to media container service");
1188                         }
1189                     } else if (mPendingInstalls.size() > 0) {
1190                         HandlerParams params = mPendingInstalls.get(0);
1191                         if (params != null) {
1192                             if (params.startCopy()) {
1193                                 // We are done...  look for more work or to
1194                                 // go idle.
1195                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
1196                                         "Checking for more work or unbind...");
1197                                 // Delete pending install
1198                                 if (mPendingInstalls.size() > 0) {
1199                                     mPendingInstalls.remove(0);
1200                                 }
1201                                 if (mPendingInstalls.size() == 0) {
1202                                     if (mBound) {
1203                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
1204                                                 "Posting delayed MCS_UNBIND");
1205                                         removeMessages(MCS_UNBIND);
1206                                         Message ubmsg = obtainMessage(MCS_UNBIND);
1207                                         // Unbind after a little delay, to avoid
1208                                         // continual thrashing.
1209                                         sendMessageDelayed(ubmsg, 10000);
1210                                     }
1211                                 } else {
1212                                     // There are more pending requests in queue.
1213                                     // Just post MCS_BOUND message to trigger processing
1214                                     // of next pending install.
1215                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
1216                                             "Posting MCS_BOUND for next work");
1217                                     mHandler.sendEmptyMessage(MCS_BOUND);
1218                                 }
1219                             }
1220                         }
1221                     } else {
1222                         // Should never happen ideally.
1223                         Slog.w(TAG, "Empty queue");
1224                     }
1225                     break;
1226                 }
1227                 case MCS_RECONNECT: {
1228                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1229                     if (mPendingInstalls.size() > 0) {
1230                         if (mBound) {
1231                             disconnectService();
1232                         }
1233                         if (!connectToService()) {
1234                             Slog.e(TAG, "Failed to bind to media container service");
1235                             for (HandlerParams params : mPendingInstalls) {
1236                                 // Indicate service bind error
1237                                 params.serviceError();
1238                             }
1239                             mPendingInstalls.clear();
1240                         }
1241                     }
1242                     break;
1243                 }
1244                 case MCS_UNBIND: {
1245                     // If there is no actual work left, then time to unbind.
1246                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1247
1248                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1249                         if (mBound) {
1250                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1251
1252                             disconnectService();
1253                         }
1254                     } else if (mPendingInstalls.size() > 0) {
1255                         // There are more pending requests in queue.
1256                         // Just post MCS_BOUND message to trigger processing
1257                         // of next pending install.
1258                         mHandler.sendEmptyMessage(MCS_BOUND);
1259                     }
1260
1261                     break;
1262                 }
1263                 case MCS_GIVE_UP: {
1264                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1265                     mPendingInstalls.remove(0);
1266                     break;
1267                 }
1268                 case SEND_PENDING_BROADCAST: {
1269                     String packages[];
1270                     ArrayList<String> components[];
1271                     int size = 0;
1272                     int uids[];
1273                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1274                     synchronized (mPackages) {
1275                         if (mPendingBroadcasts == null) {
1276                             return;
1277                         }
1278                         size = mPendingBroadcasts.size();
1279                         if (size <= 0) {
1280                             // Nothing to be done. Just return
1281                             return;
1282                         }
1283                         packages = new String[size];
1284                         components = new ArrayList[size];
1285                         uids = new int[size];
1286                         int i = 0;  // filling out the above arrays
1287
1288                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1289                             int packageUserId = mPendingBroadcasts.userIdAt(n);
1290                             Iterator<Map.Entry<String, ArrayList<String>>> it
1291                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
1292                                             .entrySet().iterator();
1293                             while (it.hasNext() && i < size) {
1294                                 Map.Entry<String, ArrayList<String>> ent = it.next();
1295                                 packages[i] = ent.getKey();
1296                                 components[i] = ent.getValue();
1297                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1298                                 uids[i] = (ps != null)
1299                                         ? UserHandle.getUid(packageUserId, ps.appId)
1300                                         : -1;
1301                                 i++;
1302                             }
1303                         }
1304                         size = i;
1305                         mPendingBroadcasts.clear();
1306                     }
1307                     // Send broadcasts
1308                     for (int i = 0; i < size; i++) {
1309                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1310                     }
1311                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1312                     break;
1313                 }
1314                 case START_CLEANING_PACKAGE: {
1315                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1316                     final String packageName = (String)msg.obj;
1317                     final int userId = msg.arg1;
1318                     final boolean andCode = msg.arg2 != 0;
1319                     synchronized (mPackages) {
1320                         if (userId == UserHandle.USER_ALL) {
1321                             int[] users = sUserManager.getUserIds();
1322                             for (int user : users) {
1323                                 mSettings.addPackageToCleanLPw(
1324                                         new PackageCleanItem(user, packageName, andCode));
1325                             }
1326                         } else {
1327                             mSettings.addPackageToCleanLPw(
1328                                     new PackageCleanItem(userId, packageName, andCode));
1329                         }
1330                     }
1331                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1332                     startCleaningPackages();
1333                 } break;
1334                 case POST_INSTALL: {
1335                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1336                     PostInstallData data = mRunningInstalls.get(msg.arg1);
1337                     mRunningInstalls.delete(msg.arg1);
1338                     boolean deleteOld = false;
1339
1340                     if (data != null) {
1341                         InstallArgs args = data.args;
1342                         PackageInstalledInfo res = data.res;
1343
1344                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1345                             final String packageName = res.pkg.applicationInfo.packageName;
1346                             res.removedInfo.sendBroadcast(false, true, false);
1347                             Bundle extras = new Bundle(1);
1348                             extras.putInt(Intent.EXTRA_UID, res.uid);
1349
1350                             // Now that we successfully installed the package, grant runtime
1351                             // permissions if requested before broadcasting the install.
1352                             if ((args.installFlags
1353                                     & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) {
1354                                 grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(),
1355                                         args.installGrantPermissions);
1356                             }
1357
1358                             // Determine the set of users who are adding this
1359                             // package for the first time vs. those who are seeing
1360                             // an update.
1361                             int[] firstUsers;
1362                             int[] updateUsers = new int[0];
1363                             if (res.origUsers == null || res.origUsers.length == 0) {
1364                                 firstUsers = res.newUsers;
1365                             } else {
1366                                 firstUsers = new int[0];
1367                                 for (int i=0; i<res.newUsers.length; i++) {
1368                                     int user = res.newUsers[i];
1369                                     boolean isNew = true;
1370                                     for (int j=0; j<res.origUsers.length; j++) {
1371                                         if (res.origUsers[j] == user) {
1372                                             isNew = false;
1373                                             break;
1374                                         }
1375                                     }
1376                                     if (isNew) {
1377                                         int[] newFirst = new int[firstUsers.length+1];
1378                                         System.arraycopy(firstUsers, 0, newFirst, 0,
1379                                                 firstUsers.length);
1380                                         newFirst[firstUsers.length] = user;
1381                                         firstUsers = newFirst;
1382                                     } else {
1383                                         int[] newUpdate = new int[updateUsers.length+1];
1384                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
1385                                                 updateUsers.length);
1386                                         newUpdate[updateUsers.length] = user;
1387                                         updateUsers = newUpdate;
1388                                     }
1389                                 }
1390                             }
1391                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1392                                     packageName, extras, null, null, firstUsers);
1393                             final boolean update = res.removedInfo.removedPackage != null;
1394                             if (update) {
1395                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1396                             }
1397                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1398                                     packageName, extras, null, null, updateUsers);
1399                             if (update) {
1400                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1401                                         packageName, extras, null, null, updateUsers);
1402                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1403                                         null, null, packageName, null, updateUsers);
1404
1405                                 // treat asec-hosted packages like removable media on upgrade
1406                                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1407                                     if (DEBUG_INSTALL) {
1408                                         Slog.i(TAG, "upgrading pkg " + res.pkg
1409                                                 + " is ASEC-hosted -> AVAILABLE");
1410                                     }
1411                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1412                                     ArrayList<String> pkgList = new ArrayList<String>(1);
1413                                     pkgList.add(packageName);
1414                                     sendResourcesChangedBroadcast(true, true,
1415                                             pkgList,uidArray, null);
1416                                 }
1417                             }
1418                             if (res.removedInfo.args != null) {
1419                                 // Remove the replaced package's older resources safely now
1420                                 deleteOld = true;
1421                             }
1422
1423                             // If this app is a browser and it's newly-installed for some
1424                             // users, clear any default-browser state in those users
1425                             if (firstUsers.length > 0) {
1426                                 // the app's nature doesn't depend on the user, so we can just
1427                                 // check its browser nature in any user and generalize.
1428                                 if (packageIsBrowser(packageName, firstUsers[0])) {
1429                                     synchronized (mPackages) {
1430                                         for (int userId : firstUsers) {
1431                                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1432                                         }
1433                                     }
1434                                 }
1435                             }
1436                             // Log current value of "unknown sources" setting
1437                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1438                                 getUnknownSourcesSettings());
1439                         }
1440                         // Force a gc to clear up things
1441                         Runtime.getRuntime().gc();
1442                         // We delete after a gc for applications  on sdcard.
1443                         if (deleteOld) {
1444                             synchronized (mInstallLock) {
1445                                 res.removedInfo.args.doPostDeleteLI(true);
1446                             }
1447                         }
1448                         if (args.observer != null) {
1449                             try {
1450                                 Bundle extras = extrasForInstallResult(res);
1451                                 args.observer.onPackageInstalled(res.name, res.returnCode,
1452                                         res.returnMsg, extras);
1453                             } catch (RemoteException e) {
1454                                 Slog.i(TAG, "Observer no longer exists.");
1455                             }
1456                         }
1457                     } else {
1458                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1459                     }
1460                 } break;
1461                 case UPDATED_MEDIA_STATUS: {
1462                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1463                     boolean reportStatus = msg.arg1 == 1;
1464                     boolean doGc = msg.arg2 == 1;
1465                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1466                     if (doGc) {
1467                         // Force a gc to clear up stale containers.
1468                         Runtime.getRuntime().gc();
1469                     }
1470                     if (msg.obj != null) {
1471                         @SuppressWarnings("unchecked")
1472                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1473                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1474                         // Unload containers
1475                         unloadAllContainers(args);
1476                     }
1477                     if (reportStatus) {
1478                         try {
1479                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1480                             PackageHelper.getMountService().finishMediaUpdate();
1481                         } catch (RemoteException e) {
1482                             Log.e(TAG, "MountService not running?");
1483                         }
1484                     }
1485                 } break;
1486                 case WRITE_SETTINGS: {
1487                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1488                     synchronized (mPackages) {
1489                         removeMessages(WRITE_SETTINGS);
1490                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1491                         mSettings.writeLPr();
1492                         mDirtyUsers.clear();
1493                     }
1494                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1495                 } break;
1496                 case WRITE_PACKAGE_RESTRICTIONS: {
1497                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1498                     synchronized (mPackages) {
1499                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1500                         for (int userId : mDirtyUsers) {
1501                             mSettings.writePackageRestrictionsLPr(userId);
1502                         }
1503                         mDirtyUsers.clear();
1504                     }
1505                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1506                 } break;
1507                 case CHECK_PENDING_VERIFICATION: {
1508                     final int verificationId = msg.arg1;
1509                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1510
1511                     if ((state != null) && !state.timeoutExtended()) {
1512                         final InstallArgs args = state.getInstallArgs();
1513                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1514
1515                         Slog.i(TAG, "Verification timed out for " + originUri);
1516                         mPendingVerification.remove(verificationId);
1517
1518                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1519
1520                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1521                             Slog.i(TAG, "Continuing with installation of " + originUri);
1522                             state.setVerifierResponse(Binder.getCallingUid(),
1523                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1524                             broadcastPackageVerified(verificationId, originUri,
1525                                     PackageManager.VERIFICATION_ALLOW,
1526                                     state.getInstallArgs().getUser());
1527                             try {
1528                                 ret = args.copyApk(mContainerService, true);
1529                             } catch (RemoteException e) {
1530                                 Slog.e(TAG, "Could not contact the ContainerService");
1531                             }
1532                         } else {
1533                             broadcastPackageVerified(verificationId, originUri,
1534                                     PackageManager.VERIFICATION_REJECT,
1535                                     state.getInstallArgs().getUser());
1536                         }
1537
1538                         processPendingInstall(args, ret);
1539                         mHandler.sendEmptyMessage(MCS_UNBIND);
1540                     }
1541                     break;
1542                 }
1543                 case PACKAGE_VERIFIED: {
1544                     final int verificationId = msg.arg1;
1545
1546                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1547                     if (state == null) {
1548                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1549                         break;
1550                     }
1551
1552                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1553
1554                     state.setVerifierResponse(response.callerUid, response.code);
1555
1556                     if (state.isVerificationComplete()) {
1557                         mPendingVerification.remove(verificationId);
1558
1559                         final InstallArgs args = state.getInstallArgs();
1560                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1561
1562                         int ret;
1563                         if (state.isInstallAllowed()) {
1564                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1565                             broadcastPackageVerified(verificationId, originUri,
1566                                     response.code, state.getInstallArgs().getUser());
1567                             try {
1568                                 ret = args.copyApk(mContainerService, true);
1569                             } catch (RemoteException e) {
1570                                 Slog.e(TAG, "Could not contact the ContainerService");
1571                             }
1572                         } else {
1573                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1574                         }
1575
1576                         processPendingInstall(args, ret);
1577
1578                         mHandler.sendEmptyMessage(MCS_UNBIND);
1579                     }
1580
1581                     break;
1582                 }
1583                 case START_INTENT_FILTER_VERIFICATIONS: {
1584                     IFVerificationParams params = (IFVerificationParams) msg.obj;
1585                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1586                             params.replacing, params.pkg);
1587                     break;
1588                 }
1589                 case INTENT_FILTER_VERIFIED: {
1590                     final int verificationId = msg.arg1;
1591
1592                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1593                             verificationId);
1594                     if (state == null) {
1595                         Slog.w(TAG, "Invalid IntentFilter verification token "
1596                                 + verificationId + " received");
1597                         break;
1598                     }
1599
1600                     final int userId = state.getUserId();
1601
1602                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1603                             "Processing IntentFilter verification with token:"
1604                             + verificationId + " and userId:" + userId);
1605
1606                     final IntentFilterVerificationResponse response =
1607                             (IntentFilterVerificationResponse) msg.obj;
1608
1609                     state.setVerifierResponse(response.callerUid, response.code);
1610
1611                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1612                             "IntentFilter verification with token:" + verificationId
1613                             + " and userId:" + userId
1614                             + " is settings verifier response with response code:"
1615                             + response.code);
1616
1617                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1618                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1619                                 + response.getFailedDomainsString());
1620                     }
1621
1622                     if (state.isVerificationComplete()) {
1623                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1624                     } else {
1625                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1626                                 "IntentFilter verification with token:" + verificationId
1627                                 + " was not said to be complete");
1628                     }
1629
1630                     break;
1631                 }
1632             }
1633         }
1634     }
1635
1636     private StorageEventListener mStorageListener = new StorageEventListener() {
1637         @Override
1638         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1639             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1640                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1641                     final String volumeUuid = vol.getFsUuid();
1642
1643                     // Clean up any users or apps that were removed or recreated
1644                     // while this volume was missing
1645                     reconcileUsers(volumeUuid);
1646                     reconcileApps(volumeUuid);
1647
1648                     // Clean up any install sessions that expired or were
1649                     // cancelled while this volume was missing
1650                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
1651
1652                     loadPrivatePackages(vol);
1653
1654                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1655                     unloadPrivatePackages(vol);
1656                 }
1657             }
1658
1659             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1660                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1661                     updateExternalMediaStatus(true, false);
1662                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1663                     updateExternalMediaStatus(false, false);
1664                 }
1665             }
1666         }
1667
1668         @Override
1669         public void onVolumeForgotten(String fsUuid) {
1670             if (TextUtils.isEmpty(fsUuid)) {
1671                 Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1672                 return;
1673             }
1674
1675             // Remove any apps installed on the forgotten volume
1676             synchronized (mPackages) {
1677                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1678                 for (PackageSetting ps : packages) {
1679                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1680                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1681                             UserHandle.USER_OWNER, PackageManager.DELETE_ALL_USERS);
1682                 }
1683
1684                 mSettings.onVolumeForgotten(fsUuid);
1685                 mSettings.writeLPr();
1686             }
1687         }
1688     };
1689
1690     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId,
1691             String[] grantedPermissions) {
1692         if (userId >= UserHandle.USER_OWNER) {
1693             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1694         } else if (userId == UserHandle.USER_ALL) {
1695             final int[] userIds;
1696             synchronized (mPackages) {
1697                 userIds = UserManagerService.getInstance().getUserIds();
1698             }
1699             for (int someUserId : userIds) {
1700                 grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions);
1701             }
1702         }
1703
1704         // We could have touched GID membership, so flush out packages.list
1705         synchronized (mPackages) {
1706             mSettings.writePackageListLPr();
1707         }
1708     }
1709
1710     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1711             String[] grantedPermissions) {
1712         SettingBase sb = (SettingBase) pkg.mExtras;
1713         if (sb == null) {
1714             return;
1715         }
1716
1717         synchronized (mPackages) {
1718             for (String permission : pkg.requestedPermissions) {
1719                 BasePermission bp = mSettings.mPermissions.get(permission);
1720                 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1721                         && (grantedPermissions == null
1722                                || ArrayUtils.contains(grantedPermissions, permission))
1723                         && (getPermissionFlags(permission, pkg.packageName, userId)
1724                                 & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) {
1725                     grantRuntimePermission(pkg.packageName, permission, userId);
1726                 }
1727             }
1728         }
1729     }
1730
1731     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1732         Bundle extras = null;
1733         switch (res.returnCode) {
1734             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1735                 extras = new Bundle();
1736                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1737                         res.origPermission);
1738                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1739                         res.origPackage);
1740                 break;
1741             }
1742             case PackageManager.INSTALL_SUCCEEDED: {
1743                 extras = new Bundle();
1744                 extras.putBoolean(Intent.EXTRA_REPLACING,
1745                         res.removedInfo != null && res.removedInfo.removedPackage != null);
1746                 break;
1747             }
1748         }
1749         return extras;
1750     }
1751
1752     void scheduleWriteSettingsLocked() {
1753         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1754             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1755         }
1756     }
1757
1758     void scheduleWritePackageRestrictionsLocked(int userId) {
1759         if (!sUserManager.exists(userId)) return;
1760         mDirtyUsers.add(userId);
1761         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1762             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1763         }
1764     }
1765
1766     public static PackageManagerService main(Context context, Installer installer,
1767             boolean factoryTest, boolean onlyCore) {
1768         PackageManagerService m = new PackageManagerService(context, installer,
1769                 factoryTest, onlyCore);
1770         ServiceManager.addService("package", m);
1771         return m;
1772     }
1773
1774     static String[] splitString(String str, char sep) {
1775         int count = 1;
1776         int i = 0;
1777         while ((i=str.indexOf(sep, i)) >= 0) {
1778             count++;
1779             i++;
1780         }
1781
1782         String[] res = new String[count];
1783         i=0;
1784         count = 0;
1785         int lastI=0;
1786         while ((i=str.indexOf(sep, i)) >= 0) {
1787             res[count] = str.substring(lastI, i);
1788             count++;
1789             i++;
1790             lastI = i;
1791         }
1792         res[count] = str.substring(lastI, str.length());
1793         return res;
1794     }
1795
1796     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1797         DisplayManager displayManager = (DisplayManager) context.getSystemService(
1798                 Context.DISPLAY_SERVICE);
1799         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1800     }
1801
1802     public PackageManagerService(Context context, Installer installer,
1803             boolean factoryTest, boolean onlyCore) {
1804         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1805                 SystemClock.uptimeMillis());
1806
1807         if (mSdkVersion <= 0) {
1808             Slog.w(TAG, "**** ro.build.version.sdk not set!");
1809         }
1810
1811         mContext = context;
1812         mFactoryTest = factoryTest;
1813         mOnlyCore = onlyCore;
1814         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1815         mMetrics = new DisplayMetrics();
1816         mSettings = new Settings(mPackages);
1817         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1818                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1819         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1820                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1821         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1822                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1823         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1824                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1825         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1826                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1827         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1828                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1829
1830         // TODO: add a property to control this?
1831         long dexOptLRUThresholdInMinutes;
1832         if (mLazyDexOpt) {
1833             dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
1834         } else {
1835             dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
1836         }
1837         mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
1838
1839         String separateProcesses = SystemProperties.get("debug.separate_processes");
1840         if (separateProcesses != null && separateProcesses.length() > 0) {
1841             if ("*".equals(separateProcesses)) {
1842                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1843                 mSeparateProcesses = null;
1844                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1845             } else {
1846                 mDefParseFlags = 0;
1847                 mSeparateProcesses = separateProcesses.split(",");
1848                 Slog.w(TAG, "Running with debug.separate_processes: "
1849                         + separateProcesses);
1850             }
1851         } else {
1852             mDefParseFlags = 0;
1853             mSeparateProcesses = null;
1854         }
1855
1856         mInstaller = installer;
1857         mPackageDexOptimizer = new PackageDexOptimizer(this);
1858         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
1859
1860         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
1861                 FgThread.get().getLooper());
1862
1863         getDefaultDisplayMetrics(context, mMetrics);
1864
1865         SystemConfig systemConfig = SystemConfig.getInstance();
1866         mGlobalGids = systemConfig.getGlobalGids();
1867         mSystemPermissions = systemConfig.getSystemPermissions();
1868         mAvailableFeatures = systemConfig.getAvailableFeatures();
1869
1870         synchronized (mInstallLock) {
1871         // writer
1872         synchronized (mPackages) {
1873             mHandlerThread = new ServiceThread(TAG,
1874                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1875             mHandlerThread.start();
1876             mHandler = new PackageHandler(mHandlerThread.getLooper());
1877             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1878
1879             File dataDir = Environment.getDataDirectory();
1880             mAppDataDir = new File(dataDir, "data");
1881             mAppInstallDir = new File(dataDir, "app");
1882             mAppLib32InstallDir = new File(dataDir, "app-lib");
1883             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1884             mUserAppDataDir = new File(dataDir, "user");
1885             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1886
1887             sUserManager = new UserManagerService(context, this,
1888                     mInstallLock, mPackages);
1889
1890             // Propagate permission configuration in to package manager.
1891             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1892                     = systemConfig.getPermissions();
1893             for (int i=0; i<permConfig.size(); i++) {
1894                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1895                 BasePermission bp = mSettings.mPermissions.get(perm.name);
1896                 if (bp == null) {
1897                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1898                     mSettings.mPermissions.put(perm.name, bp);
1899                 }
1900                 if (perm.gids != null) {
1901                     bp.setGids(perm.gids, perm.perUser);
1902                 }
1903             }
1904
1905             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1906             for (int i=0; i<libConfig.size(); i++) {
1907                 mSharedLibraries.put(libConfig.keyAt(i),
1908                         new SharedLibraryEntry(libConfig.valueAt(i), null));
1909             }
1910
1911             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1912
1913             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1914                     mSdkVersion, mOnlyCore);
1915
1916             String customResolverActivity = Resources.getSystem().getString(
1917                     R.string.config_customResolverActivity);
1918             if (TextUtils.isEmpty(customResolverActivity)) {
1919                 customResolverActivity = null;
1920             } else {
1921                 mCustomResolverComponentName = ComponentName.unflattenFromString(
1922                         customResolverActivity);
1923             }
1924
1925             long startTime = SystemClock.uptimeMillis();
1926
1927             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1928                     startTime);
1929
1930             // Set flag to monitor and not change apk file paths when
1931             // scanning install directories.
1932             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
1933
1934             final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
1935
1936             /**
1937              * Add everything in the in the boot class path to the
1938              * list of process files because dexopt will have been run
1939              * if necessary during zygote startup.
1940              */
1941             final String bootClassPath = System.getenv("BOOTCLASSPATH");
1942             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1943
1944             if (bootClassPath != null) {
1945                 String[] bootClassPathElements = splitString(bootClassPath, ':');
1946                 for (String element : bootClassPathElements) {
1947                     alreadyDexOpted.add(element);
1948                 }
1949             } else {
1950                 Slog.w(TAG, "No BOOTCLASSPATH found!");
1951             }
1952
1953             if (systemServerClassPath != null) {
1954                 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1955                 for (String element : systemServerClassPathElements) {
1956                     alreadyDexOpted.add(element);
1957                 }
1958             } else {
1959                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1960             }
1961
1962             final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
1963             final String[] dexCodeInstructionSets =
1964                     getDexCodeInstructionSets(
1965                             allInstructionSets.toArray(new String[allInstructionSets.size()]));
1966
1967             /**
1968              * Ensure all external libraries have had dexopt run on them.
1969              */
1970             if (mSharedLibraries.size() > 0) {
1971                 // NOTE: For now, we're compiling these system "shared libraries"
1972                 // (and framework jars) into all available architectures. It's possible
1973                 // to compile them only when we come across an app that uses them (there's
1974                 // already logic for that in scanPackageLI) but that adds some complexity.
1975                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1976                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1977                         final String lib = libEntry.path;
1978                         if (lib == null) {
1979                             continue;
1980                         }
1981
1982                         try {
1983                             int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
1984                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
1985                                 alreadyDexOpted.add(lib);
1986                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
1987                             }
1988                         } catch (FileNotFoundException e) {
1989                             Slog.w(TAG, "Library not found: " + lib);
1990                         } catch (IOException e) {
1991                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1992                                     + e.getMessage());
1993                         }
1994                     }
1995                 }
1996             }
1997
1998             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1999
2000             // Gross hack for now: we know this file doesn't contain any
2001             // code, so don't dexopt it to avoid the resulting log spew.
2002             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
2003
2004             // Gross hack for now: we know this file is only part of
2005             // the boot class path for art, so don't dexopt it to
2006             // avoid the resulting log spew.
2007             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
2008
2009             /**
2010              * There are a number of commands implemented in Java, which
2011              * we currently need to do the dexopt on so that they can be
2012              * run from a non-root shell.
2013              */
2014             String[] frameworkFiles = frameworkDir.list();
2015             if (frameworkFiles != null) {
2016                 // TODO: We could compile these only for the most preferred ABI. We should
2017                 // first double check that the dex files for these commands are not referenced
2018                 // by other system apps.
2019                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2020                     for (int i=0; i<frameworkFiles.length; i++) {
2021                         File libPath = new File(frameworkDir, frameworkFiles[i]);
2022                         String path = libPath.getPath();
2023                         // Skip the file if we already did it.
2024                         if (alreadyDexOpted.contains(path)) {
2025                             continue;
2026                         }
2027                         // Skip the file if it is not a type we want to dexopt.
2028                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
2029                             continue;
2030                         }
2031                         try {
2032                             int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
2033                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2034                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
2035                             }
2036                         } catch (FileNotFoundException e) {
2037                             Slog.w(TAG, "Jar not found: " + path);
2038                         } catch (IOException e) {
2039                             Slog.w(TAG, "Exception reading jar: " + path, e);
2040                         }
2041                     }
2042                 }
2043             }
2044
2045             final VersionInfo ver = mSettings.getInternalVersion();
2046             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2047             // when upgrading from pre-M, promote system app permissions from install to runtime
2048             mPromoteSystemApps =
2049                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2050
2051             // save off the names of pre-existing system packages prior to scanning; we don't
2052             // want to automatically grant runtime permissions for new system apps
2053             if (mPromoteSystemApps) {
2054                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2055                 while (pkgSettingIter.hasNext()) {
2056                     PackageSetting ps = pkgSettingIter.next();
2057                     if (isSystemApp(ps)) {
2058                         mExistingSystemPackages.add(ps.name);
2059                     }
2060                 }
2061             }
2062
2063             // Collect vendor overlay packages.
2064             // (Do this before scanning any apps.)
2065             // For security and version matching reason, only consider
2066             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
2067             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
2068             scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
2069                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2070
2071             // Find base frameworks (resource packages without code).
2072             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
2073                     | PackageParser.PARSE_IS_SYSTEM_DIR
2074                     | PackageParser.PARSE_IS_PRIVILEGED,
2075                     scanFlags | SCAN_NO_DEX, 0);
2076
2077             // Collected privileged system packages.
2078             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2079             scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
2080                     | PackageParser.PARSE_IS_SYSTEM_DIR
2081                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2082
2083             // Collect ordinary system packages.
2084             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2085             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
2086                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2087
2088             // Collect all vendor packages.
2089             File vendorAppDir = new File("/vendor/app");
2090             try {
2091                 vendorAppDir = vendorAppDir.getCanonicalFile();
2092             } catch (IOException e) {
2093                 // failed to look up canonical path, continue with original one
2094             }
2095             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
2096                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2097
2098             // Collect all OEM packages.
2099             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2100             scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
2101                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2102
2103             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
2104             mInstaller.moveFiles();
2105
2106             // Prune any system packages that no longer exist.
2107             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2108             if (!mOnlyCore) {
2109                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2110                 while (psit.hasNext()) {
2111                     PackageSetting ps = psit.next();
2112
2113                     /*
2114                      * If this is not a system app, it can't be a
2115                      * disable system app.
2116                      */
2117                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2118                         continue;
2119                     }
2120
2121                     /*
2122                      * If the package is scanned, it's not erased.
2123                      */
2124                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2125                     if (scannedPkg != null) {
2126                         /*
2127                          * If the system app is both scanned and in the
2128                          * disabled packages list, then it must have been
2129                          * added via OTA. Remove it from the currently
2130                          * scanned package so the previously user-installed
2131                          * application can be scanned.
2132                          */
2133                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2134                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2135                                     + ps.name + "; removing system app.  Last known codePath="
2136                                     + ps.codePathString + ", installStatus=" + ps.installStatus
2137                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2138                                     + scannedPkg.mVersionCode);
2139                             removePackageLI(ps, true);
2140                             mExpectingBetter.put(ps.name, ps.codePath);
2141                         }
2142
2143                         continue;
2144                     }
2145
2146                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2147                         psit.remove();
2148                         logCriticalInfo(Log.WARN, "System package " + ps.name
2149                                 + " no longer exists; wiping its data");
2150                         removeDataDirsLI(null, ps.name);
2151                     } else {
2152                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2153                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2154                             possiblyDeletedUpdatedSystemApps.add(ps.name);
2155                         }
2156                     }
2157                 }
2158             }
2159
2160             //look for any incomplete package installations
2161             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2162             //clean up list
2163             for(int i = 0; i < deletePkgsList.size(); i++) {
2164                 //clean up here
2165                 cleanupInstallFailedPackage(deletePkgsList.get(i));
2166             }
2167             //delete tmp files
2168             deleteTempPackageFiles();
2169
2170             // Remove any shared userIDs that have no associated packages
2171             mSettings.pruneSharedUsersLPw();
2172
2173             if (!mOnlyCore) {
2174                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2175                         SystemClock.uptimeMillis());
2176                 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2177
2178                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
2179                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2180
2181                 /**
2182                  * Remove disable package settings for any updated system
2183                  * apps that were removed via an OTA. If they're not a
2184                  * previously-updated app, remove them completely.
2185                  * Otherwise, just revoke their system-level permissions.
2186                  */
2187                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2188                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2189                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2190
2191                     String msg;
2192                     if (deletedPkg == null) {
2193                         msg = "Updated system package " + deletedAppName
2194                                 + " no longer exists; wiping its data";
2195                         removeDataDirsLI(null, deletedAppName);
2196                     } else {
2197                         msg = "Updated system app + " + deletedAppName
2198                                 + " no longer present; removing system privileges for "
2199                                 + deletedAppName;
2200
2201                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2202
2203                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2204                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2205                     }
2206                     logCriticalInfo(Log.WARN, msg);
2207                 }
2208
2209                 /**
2210                  * Make sure all system apps that we expected to appear on
2211                  * the userdata partition actually showed up. If they never
2212                  * appeared, crawl back and revive the system version.
2213                  */
2214                 for (int i = 0; i < mExpectingBetter.size(); i++) {
2215                     final String packageName = mExpectingBetter.keyAt(i);
2216                     if (!mPackages.containsKey(packageName)) {
2217                         final File scanFile = mExpectingBetter.valueAt(i);
2218
2219                         logCriticalInfo(Log.WARN, "Expected better " + packageName
2220                                 + " but never showed up; reverting to system");
2221
2222                         final int reparseFlags;
2223                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
2224                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2225                                     | PackageParser.PARSE_IS_SYSTEM_DIR
2226                                     | PackageParser.PARSE_IS_PRIVILEGED;
2227                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
2228                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2229                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2230                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2231                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2232                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2233                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
2234                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2235                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2236                         } else {
2237                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2238                             continue;
2239                         }
2240
2241                         mSettings.enableSystemPackageLPw(packageName);
2242
2243                         try {
2244                             scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
2245                         } catch (PackageManagerException e) {
2246                             Slog.e(TAG, "Failed to parse original system package: "
2247                                     + e.getMessage());
2248                         }
2249                     }
2250                 }
2251             }
2252             mExpectingBetter.clear();
2253
2254             // Now that we know all of the shared libraries, update all clients to have
2255             // the correct library paths.
2256             updateAllSharedLibrariesLPw();
2257
2258             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2259                 // NOTE: We ignore potential failures here during a system scan (like
2260                 // the rest of the commands above) because there's precious little we
2261                 // can do about it. A settings error is reported, though.
2262                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2263                         false /* force dexopt */, false /* defer dexopt */,
2264                         false /* boot complete */);
2265             }
2266
2267             // Now that we know all the packages we are keeping,
2268             // read and update their last usage times.
2269             mPackageUsage.readLP();
2270
2271             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2272                     SystemClock.uptimeMillis());
2273             Slog.i(TAG, "Time to scan packages: "
2274                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
2275                     + " seconds");
2276
2277             // If the platform SDK has changed since the last time we booted,
2278             // we need to re-grant app permission to catch any new ones that
2279             // appear.  This is really a hack, and means that apps can in some
2280             // cases get permissions that the user didn't initially explicitly
2281             // allow...  it would be nice to have some better way to handle
2282             // this situation.
2283             int updateFlags = UPDATE_PERMISSIONS_ALL;
2284             if (ver.sdkVersion != mSdkVersion) {
2285                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2286                         + mSdkVersion + "; regranting permissions for internal storage");
2287                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2288             }
2289             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2290             ver.sdkVersion = mSdkVersion;
2291
2292             // If this is the first boot or an update from pre-M, and it is a normal
2293             // boot, then we need to initialize the default preferred apps across
2294             // all defined users.
2295             if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
2296                 for (UserInfo user : sUserManager.getUsers(true)) {
2297                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2298                     applyFactoryDefaultBrowserLPw(user.id);
2299                     primeDomainVerificationsLPw(user.id);
2300                 }
2301             }
2302
2303             // If this is first boot after an OTA, and a normal boot, then
2304             // we need to clear code cache directories.
2305             if (mIsUpgrade && !onlyCore) {
2306                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2307                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2308                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
2309                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2310                         deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
2311                     }
2312                 }
2313                 ver.fingerprint = Build.FINGERPRINT;
2314             }
2315
2316             checkDefaultBrowser();
2317
2318             // clear only after permissions and other defaults have been updated
2319             mExistingSystemPackages.clear();
2320             mPromoteSystemApps = false;
2321
2322             // All the changes are done during package scanning.
2323             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2324
2325             // can downgrade to reader
2326             mSettings.writeLPr();
2327
2328             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2329                     SystemClock.uptimeMillis());
2330
2331             mRequiredVerifierPackage = getRequiredVerifierLPr();
2332             mRequiredInstallerPackage = getRequiredInstallerLPr();
2333
2334             mInstallerService = new PackageInstallerService(context, this);
2335
2336             mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2337             mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2338                     mIntentFilterVerifierComponent);
2339
2340         } // synchronized (mPackages)
2341         } // synchronized (mInstallLock)
2342
2343         // Now after opening every single application zip, make sure they
2344         // are all flushed.  Not really needed, but keeps things nice and
2345         // tidy.
2346         Runtime.getRuntime().gc();
2347
2348         // Expose private service for system components to use.
2349         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2350     }
2351
2352     @Override
2353     public boolean isFirstBoot() {
2354         return !mRestoredSettings;
2355     }
2356
2357     @Override
2358     public boolean isOnlyCoreApps() {
2359         return mOnlyCore;
2360     }
2361
2362     @Override
2363     public boolean isUpgrade() {
2364         return mIsUpgrade;
2365     }
2366
2367     private String getRequiredVerifierLPr() {
2368         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2369         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2370                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
2371
2372         String requiredVerifier = null;
2373
2374         final int N = receivers.size();
2375         for (int i = 0; i < N; i++) {
2376             final ResolveInfo info = receivers.get(i);
2377
2378             if (info.activityInfo == null) {
2379                 continue;
2380             }
2381
2382             final String packageName = info.activityInfo.packageName;
2383
2384             if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
2385                     packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2386                 continue;
2387             }
2388
2389             if (requiredVerifier != null) {
2390                 throw new RuntimeException("There can be only one required verifier");
2391             }
2392
2393             requiredVerifier = packageName;
2394         }
2395
2396         return requiredVerifier;
2397     }
2398
2399     private String getRequiredInstallerLPr() {
2400         Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2401         installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
2402         installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2403
2404         final List<ResolveInfo> installers = queryIntentActivities(installerIntent,
2405                 PACKAGE_MIME_TYPE, 0, 0);
2406
2407         String requiredInstaller = null;
2408
2409         final int N = installers.size();
2410         for (int i = 0; i < N; i++) {
2411             final ResolveInfo info = installers.get(i);
2412             final String packageName = info.activityInfo.packageName;
2413
2414             if (!info.activityInfo.applicationInfo.isSystemApp()) {
2415                 continue;
2416             }
2417
2418             if (requiredInstaller != null) {
2419                 throw new RuntimeException("There must be one required installer");
2420             }
2421
2422             requiredInstaller = packageName;
2423         }
2424
2425         if (requiredInstaller == null) {
2426             throw new RuntimeException("There must be one required installer");
2427         }
2428
2429         return requiredInstaller;
2430     }
2431
2432     private ComponentName getIntentFilterVerifierComponentNameLPr() {
2433         final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2434         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2435                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */);
2436
2437         ComponentName verifierComponentName = null;
2438
2439         int priority = -1000;
2440         final int N = receivers.size();
2441         for (int i = 0; i < N; i++) {
2442             final ResolveInfo info = receivers.get(i);
2443
2444             if (info.activityInfo == null) {
2445                 continue;
2446             }
2447
2448             final String packageName = info.activityInfo.packageName;
2449
2450             final PackageSetting ps = mSettings.mPackages.get(packageName);
2451             if (ps == null) {
2452                 continue;
2453             }
2454
2455             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2456                     packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2457                 continue;
2458             }
2459
2460             // Select the IntentFilterVerifier with the highest priority
2461             if (priority < info.priority) {
2462                 priority = info.priority;
2463                 verifierComponentName = new ComponentName(packageName, info.activityInfo.name);
2464                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Selecting IntentFilterVerifier: "
2465                         + verifierComponentName + " with priority: " + info.priority);
2466             }
2467         }
2468
2469         return verifierComponentName;
2470     }
2471
2472     private void primeDomainVerificationsLPw(int userId) {
2473         if (DEBUG_DOMAIN_VERIFICATION) {
2474             Slog.d(TAG, "Priming domain verifications in user " + userId);
2475         }
2476
2477         SystemConfig systemConfig = SystemConfig.getInstance();
2478         ArraySet<String> packages = systemConfig.getLinkedApps();
2479         ArraySet<String> domains = new ArraySet<String>();
2480
2481         for (String packageName : packages) {
2482             PackageParser.Package pkg = mPackages.get(packageName);
2483             if (pkg != null) {
2484                 if (!pkg.isSystemApp()) {
2485                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2486                     continue;
2487                 }
2488
2489                 domains.clear();
2490                 for (PackageParser.Activity a : pkg.activities) {
2491                     for (ActivityIntentInfo filter : a.intents) {
2492                         if (hasValidDomains(filter)) {
2493                             domains.addAll(filter.getHostsList());
2494                         }
2495                     }
2496                 }
2497
2498                 if (domains.size() > 0) {
2499                     if (DEBUG_DOMAIN_VERIFICATION) {
2500                         Slog.v(TAG, "      + " + packageName);
2501                     }
2502                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2503                     // state w.r.t. the formal app-linkage "no verification attempted" state;
2504                     // and then 'always' in the per-user state actually used for intent resolution.
2505                     final IntentFilterVerificationInfo ivi;
2506                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2507                             new ArrayList<String>(domains));
2508                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2509                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2510                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2511                 } else {
2512                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2513                             + "' does not handle web links");
2514                 }
2515             } else {
2516                 Slog.w(TAG, "Unknown package '" + packageName + "' in sysconfig <app-link>");
2517             }
2518         }
2519
2520         scheduleWritePackageRestrictionsLocked(userId);
2521         scheduleWriteSettingsLocked();
2522     }
2523
2524     private void applyFactoryDefaultBrowserLPw(int userId) {
2525         // The default browser app's package name is stored in a string resource,
2526         // with a product-specific overlay used for vendor customization.
2527         String browserPkg = mContext.getResources().getString(
2528                 com.android.internal.R.string.default_browser);
2529         if (!TextUtils.isEmpty(browserPkg)) {
2530             // non-empty string => required to be a known package
2531             PackageSetting ps = mSettings.mPackages.get(browserPkg);
2532             if (ps == null) {
2533                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2534                 browserPkg = null;
2535             } else {
2536                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2537             }
2538         }
2539
2540         // Nothing valid explicitly set? Make the factory-installed browser the explicit
2541         // default.  If there's more than one, just leave everything alone.
2542         if (browserPkg == null) {
2543             calculateDefaultBrowserLPw(userId);
2544         }
2545     }
2546
2547     private void calculateDefaultBrowserLPw(int userId) {
2548         List<String> allBrowsers = resolveAllBrowserApps(userId);
2549         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2550         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2551     }
2552
2553     private List<String> resolveAllBrowserApps(int userId) {
2554         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2555         List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2556                 PackageManager.MATCH_ALL, userId);
2557
2558         final int count = list.size();
2559         List<String> result = new ArrayList<String>(count);
2560         for (int i=0; i<count; i++) {
2561             ResolveInfo info = list.get(i);
2562             if (info.activityInfo == null
2563                     || !info.handleAllWebDataURI
2564                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2565                     || result.contains(info.activityInfo.packageName)) {
2566                 continue;
2567             }
2568             result.add(info.activityInfo.packageName);
2569         }
2570
2571         return result;
2572     }
2573
2574     private boolean packageIsBrowser(String packageName, int userId) {
2575         List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2576                 PackageManager.MATCH_ALL, userId);
2577         final int N = list.size();
2578         for (int i = 0; i < N; i++) {
2579             ResolveInfo info = list.get(i);
2580             if (packageName.equals(info.activityInfo.packageName)) {
2581                 return true;
2582             }
2583         }
2584         return false;
2585     }
2586
2587     private void checkDefaultBrowser() {
2588         final int myUserId = UserHandle.myUserId();
2589         final String packageName = getDefaultBrowserPackageName(myUserId);
2590         if (packageName != null) {
2591             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2592             if (info == null) {
2593                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
2594                 synchronized (mPackages) {
2595                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
2596                 }
2597             }
2598         }
2599     }
2600
2601     @Override
2602     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2603             throws RemoteException {
2604         try {
2605             return super.onTransact(code, data, reply, flags);
2606         } catch (RuntimeException e) {
2607             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2608                 Slog.wtf(TAG, "Package Manager Crash", e);
2609             }
2610             throw e;
2611         }
2612     }
2613
2614     void cleanupInstallFailedPackage(PackageSetting ps) {
2615         logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2616
2617         removeDataDirsLI(ps.volumeUuid, ps.name);
2618         if (ps.codePath != null) {
2619             if (ps.codePath.isDirectory()) {
2620                 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath());
2621             } else {
2622                 ps.codePath.delete();
2623             }
2624         }
2625         if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2626             if (ps.resourcePath.isDirectory()) {
2627                 FileUtils.deleteContents(ps.resourcePath);
2628             }
2629             ps.resourcePath.delete();
2630         }
2631         mSettings.removePackageLPw(ps.name);
2632     }
2633
2634     static int[] appendInts(int[] cur, int[] add) {
2635         if (add == null) return cur;
2636         if (cur == null) return add;
2637         final int N = add.length;
2638         for (int i=0; i<N; i++) {
2639             cur = appendInt(cur, add[i]);
2640         }
2641         return cur;
2642     }
2643
2644     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
2645         if (!sUserManager.exists(userId)) return null;
2646         final PackageSetting ps = (PackageSetting) p.mExtras;
2647         if (ps == null) {
2648             return null;
2649         }
2650
2651         final PermissionsState permissionsState = ps.getPermissionsState();
2652
2653         final int[] gids = permissionsState.computeGids(userId);
2654         final Set<String> permissions = permissionsState.getPermissions(userId);
2655         final PackageUserState state = ps.readUserState(userId);
2656
2657         return PackageParser.generatePackageInfo(p, gids, flags,
2658                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2659     }
2660
2661     @Override
2662     public boolean isPackageFrozen(String packageName) {
2663         synchronized (mPackages) {
2664             final PackageSetting ps = mSettings.mPackages.get(packageName);
2665             if (ps != null) {
2666                 return ps.frozen;
2667             }
2668         }
2669         Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen");
2670         return true;
2671     }
2672
2673     @Override
2674     public boolean isPackageAvailable(String packageName, int userId) {
2675         if (!sUserManager.exists(userId)) return false;
2676         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
2677         synchronized (mPackages) {
2678             PackageParser.Package p = mPackages.get(packageName);
2679             if (p != null) {
2680                 final PackageSetting ps = (PackageSetting) p.mExtras;
2681                 if (ps != null) {
2682                     final PackageUserState state = ps.readUserState(userId);
2683                     if (state != null) {
2684                         return PackageParser.isAvailable(state);
2685                     }
2686                 }
2687             }
2688         }
2689         return false;
2690     }
2691
2692     @Override
2693     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2694         if (!sUserManager.exists(userId)) return null;
2695         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
2696         // reader
2697         synchronized (mPackages) {
2698             PackageParser.Package p = mPackages.get(packageName);
2699             if (DEBUG_PACKAGE_INFO)
2700                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2701             if (p != null) {
2702                 return generatePackageInfo(p, flags, userId);
2703             }
2704             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2705                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
2706             }
2707         }
2708         return null;
2709     }
2710
2711     @Override
2712     public String[] currentToCanonicalPackageNames(String[] names) {
2713         String[] out = new String[names.length];
2714         // reader
2715         synchronized (mPackages) {
2716             for (int i=names.length-1; i>=0; i--) {
2717                 PackageSetting ps = mSettings.mPackages.get(names[i]);
2718                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
2719             }
2720         }
2721         return out;
2722     }
2723
2724     @Override
2725     public String[] canonicalToCurrentPackageNames(String[] names) {
2726         String[] out = new String[names.length];
2727         // reader
2728         synchronized (mPackages) {
2729             for (int i=names.length-1; i>=0; i--) {
2730                 String cur = mSettings.mRenamedPackages.get(names[i]);
2731                 out[i] = cur != null ? cur : names[i];
2732             }
2733         }
2734         return out;
2735     }
2736
2737     @Override
2738     public int getPackageUid(String packageName, int userId) {
2739         return getPackageUidEtc(packageName, 0, userId);
2740     }
2741
2742     @Override
2743     public int getPackageUidEtc(String packageName, int flags, int userId) {
2744         if (!sUserManager.exists(userId)) return -1;
2745         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
2746
2747         // reader
2748         synchronized (mPackages) {
2749             final PackageParser.Package p = mPackages.get(packageName);
2750             if (p != null) {
2751                 return UserHandle.getUid(userId, p.applicationInfo.uid);
2752             }
2753             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2754                 final PackageSetting ps = mSettings.mPackages.get(packageName);
2755                 if (ps != null) {
2756                     return UserHandle.getUid(userId, ps.appId);
2757                 }
2758             }
2759         }
2760
2761         return -1;
2762     }
2763
2764     @Override
2765     public int[] getPackageGids(String packageName, int userId) {
2766         return getPackageGidsEtc(packageName, 0, userId);
2767     }
2768
2769     @Override
2770     public int[] getPackageGidsEtc(String packageName, int flags, int userId) {
2771         if (!sUserManager.exists(userId)) {
2772             return null;
2773         }
2774
2775         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
2776                 "getPackageGids");
2777
2778         // reader
2779         synchronized (mPackages) {
2780             final PackageParser.Package p = mPackages.get(packageName);
2781             if (p != null) {
2782                 PackageSetting ps = (PackageSetting) p.mExtras;
2783                 return ps.getPermissionsState().computeGids(userId);
2784             }
2785             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2786                 final PackageSetting ps = mSettings.mPackages.get(packageName);
2787                 if (ps != null) {
2788                     return ps.getPermissionsState().computeGids(userId);
2789                 }
2790             }
2791         }
2792
2793         return null;
2794     }
2795
2796     static PermissionInfo generatePermissionInfo(
2797             BasePermission bp, int flags) {
2798         if (bp.perm != null) {
2799             return PackageParser.generatePermissionInfo(bp.perm, flags);
2800         }
2801         PermissionInfo pi = new PermissionInfo();
2802         pi.name = bp.name;
2803         pi.packageName = bp.sourcePackage;
2804         pi.nonLocalizedLabel = bp.name;
2805         pi.protectionLevel = bp.protectionLevel;
2806         return pi;
2807     }
2808
2809     @Override
2810     public PermissionInfo getPermissionInfo(String name, int flags) {
2811         // reader
2812         synchronized (mPackages) {
2813             final BasePermission p = mSettings.mPermissions.get(name);
2814             if (p != null) {
2815                 return generatePermissionInfo(p, flags);
2816             }
2817             return null;
2818         }
2819     }
2820
2821     @Override
2822     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2823         // reader
2824         synchronized (mPackages) {
2825             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2826             for (BasePermission p : mSettings.mPermissions.values()) {
2827                 if (group == null) {
2828                     if (p.perm == null || p.perm.info.group == null) {
2829                         out.add(generatePermissionInfo(p, flags));
2830                     }
2831                 } else {
2832                     if (p.perm != null && group.equals(p.perm.info.group)) {
2833                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2834                     }
2835                 }
2836             }
2837
2838             if (out.size() > 0) {
2839                 return out;
2840             }
2841             return mPermissionGroups.containsKey(group) ? out : null;
2842         }
2843     }
2844
2845     @Override
2846     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2847         // reader
2848         synchronized (mPackages) {
2849             return PackageParser.generatePermissionGroupInfo(
2850                     mPermissionGroups.get(name), flags);
2851         }
2852     }
2853
2854     @Override
2855     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2856         // reader
2857         synchronized (mPackages) {
2858             final int N = mPermissionGroups.size();
2859             ArrayList<PermissionGroupInfo> out
2860                     = new ArrayList<PermissionGroupInfo>(N);
2861             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2862                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2863             }
2864             return out;
2865         }
2866     }
2867
2868     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2869             int userId) {
2870         if (!sUserManager.exists(userId)) return null;
2871         PackageSetting ps = mSettings.mPackages.get(packageName);
2872         if (ps != null) {
2873             if (ps.pkg == null) {
2874                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2875                         flags, userId);
2876                 if (pInfo != null) {
2877                     return pInfo.applicationInfo;
2878                 }
2879                 return null;
2880             }
2881             return PackageParser.generateApplicationInfo(ps.pkg, flags,
2882                     ps.readUserState(userId), userId);
2883         }
2884         return null;
2885     }
2886
2887     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2888             int userId) {
2889         if (!sUserManager.exists(userId)) return null;
2890         PackageSetting ps = mSettings.mPackages.get(packageName);
2891         if (ps != null) {
2892             PackageParser.Package pkg = ps.pkg;
2893             if (pkg == null) {
2894                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2895                     return null;
2896                 }
2897                 // Only data remains, so we aren't worried about code paths
2898                 pkg = new PackageParser.Package(packageName);
2899                 pkg.applicationInfo.packageName = packageName;
2900                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2901                 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
2902                 pkg.applicationInfo.dataDir = Environment
2903                         .getDataUserPackageDirectory(ps.volumeUuid, userId, packageName)
2904                         .getAbsolutePath();
2905                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2906                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2907             }
2908             return generatePackageInfo(pkg, flags, userId);
2909         }
2910         return null;
2911     }
2912
2913     @Override
2914     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2915         if (!sUserManager.exists(userId)) return null;
2916         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2917         // writer
2918         synchronized (mPackages) {
2919             PackageParser.Package p = mPackages.get(packageName);
2920             if (DEBUG_PACKAGE_INFO) Log.v(
2921                     TAG, "getApplicationInfo " + packageName
2922                     + ": " + p);
2923             if (p != null) {
2924                 PackageSetting ps = mSettings.mPackages.get(packageName);
2925                 if (ps == null) return null;
2926                 // Note: isEnabledLP() does not apply here - always return info
2927                 return PackageParser.generateApplicationInfo(
2928                         p, flags, ps.readUserState(userId), userId);
2929             }
2930             if ("android".equals(packageName)||"system".equals(packageName)) {
2931                 return mAndroidApplication;
2932             }
2933             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2934                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2935             }
2936         }
2937         return null;
2938     }
2939
2940     @Override
2941     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
2942             final IPackageDataObserver observer) {
2943         mContext.enforceCallingOrSelfPermission(
2944                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2945         // Queue up an async operation since clearing cache may take a little while.
2946         mHandler.post(new Runnable() {
2947             public void run() {
2948                 mHandler.removeCallbacks(this);
2949                 int retCode = -1;
2950                 synchronized (mInstallLock) {
2951                     retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2952                     if (retCode < 0) {
2953                         Slog.w(TAG, "Couldn't clear application caches");
2954                     }
2955                 }
2956                 if (observer != null) {
2957                     try {
2958                         observer.onRemoveCompleted(null, (retCode >= 0));
2959                     } catch (RemoteException e) {
2960                         Slog.w(TAG, "RemoveException when invoking call back");
2961                     }
2962                 }
2963             }
2964         });
2965     }
2966
2967     @Override
2968     public void freeStorage(final String volumeUuid, final long freeStorageSize,
2969             final IntentSender pi) {
2970         mContext.enforceCallingOrSelfPermission(
2971                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2972         // Queue up an async operation since clearing cache may take a little while.
2973         mHandler.post(new Runnable() {
2974             public void run() {
2975                 mHandler.removeCallbacks(this);
2976                 int retCode = -1;
2977                 synchronized (mInstallLock) {
2978                     retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2979                     if (retCode < 0) {
2980                         Slog.w(TAG, "Couldn't clear application caches");
2981                     }
2982                 }
2983                 if(pi != null) {
2984                     try {
2985                         // Callback via pending intent
2986                         int code = (retCode >= 0) ? 1 : 0;
2987                         pi.sendIntent(null, code, null,
2988                                 null, null);
2989                     } catch (SendIntentException e1) {
2990                         Slog.i(TAG, "Failed to send pending intent");
2991                     }
2992                 }
2993             }
2994         });
2995     }
2996
2997     void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
2998         synchronized (mInstallLock) {
2999             if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) {
3000                 throw new IOException("Failed to free enough space");
3001             }
3002         }
3003     }
3004
3005     @Override
3006     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3007         if (!sUserManager.exists(userId)) return null;
3008         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
3009         synchronized (mPackages) {
3010             PackageParser.Activity a = mActivities.mActivities.get(component);
3011
3012             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3013             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
3014                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3015                 if (ps == null) return null;
3016                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3017                         userId);
3018             }
3019             if (mResolveComponentName.equals(component)) {
3020                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
3021                         new PackageUserState(), userId);
3022             }
3023         }
3024         return null;
3025     }
3026
3027     @Override
3028     public boolean activitySupportsIntent(ComponentName component, Intent intent,
3029             String resolvedType) {
3030         synchronized (mPackages) {
3031             if (component.equals(mResolveComponentName)) {
3032                 // The resolver supports EVERYTHING!
3033                 return true;
3034             }
3035             PackageParser.Activity a = mActivities.mActivities.get(component);
3036             if (a == null) {
3037                 return false;
3038             }
3039             for (int i=0; i<a.intents.size(); i++) {
3040                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3041                         intent.getData(), intent.getCategories(), TAG) >= 0) {
3042                     return true;
3043                 }
3044             }
3045             return false;
3046         }
3047     }
3048
3049     @Override
3050     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3051         if (!sUserManager.exists(userId)) return null;
3052         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
3053         synchronized (mPackages) {
3054             PackageParser.Activity a = mReceivers.mActivities.get(component);
3055             if (DEBUG_PACKAGE_INFO) Log.v(
3056                 TAG, "getReceiverInfo " + component + ": " + a);
3057             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
3058                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3059                 if (ps == null) return null;
3060                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3061                         userId);
3062             }
3063         }
3064         return null;
3065     }
3066
3067     @Override
3068     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3069         if (!sUserManager.exists(userId)) return null;
3070         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
3071         synchronized (mPackages) {
3072             PackageParser.Service s = mServices.mServices.get(component);
3073             if (DEBUG_PACKAGE_INFO) Log.v(
3074                 TAG, "getServiceInfo " + component + ": " + s);
3075             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
3076                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3077                 if (ps == null) return null;
3078                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3079                         userId);
3080             }
3081         }
3082         return null;
3083     }
3084
3085     @Override
3086     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3087         if (!sUserManager.exists(userId)) return null;
3088         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
3089         synchronized (mPackages) {
3090             PackageParser.Provider p = mProviders.mProviders.get(component);
3091             if (DEBUG_PACKAGE_INFO) Log.v(
3092                 TAG, "getProviderInfo " + component + ": " + p);
3093             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
3094                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3095                 if (ps == null) return null;
3096                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3097                         userId);
3098             }
3099         }
3100         return null;
3101     }
3102
3103     @Override
3104     public String[] getSystemSharedLibraryNames() {
3105         Set<String> libSet;
3106         synchronized (mPackages) {
3107             libSet = mSharedLibraries.keySet();
3108             int size = libSet.size();
3109             if (size > 0) {
3110                 String[] libs = new String[size];
3111                 libSet.toArray(libs);
3112                 return libs;
3113             }
3114         }
3115         return null;
3116     }
3117
3118     /**
3119      * @hide
3120      */
3121     PackageParser.Package findSharedNonSystemLibrary(String libName) {
3122         synchronized (mPackages) {
3123             PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
3124             if (lib != null && lib.apk != null) {
3125                 return mPackages.get(lib.apk);
3126             }
3127         }
3128         return null;
3129     }
3130
3131     @Override
3132     public FeatureInfo[] getSystemAvailableFeatures() {
3133         Collection<FeatureInfo> featSet;
3134         synchronized (mPackages) {
3135             featSet = mAvailableFeatures.values();
3136             int size = featSet.size();
3137             if (size > 0) {
3138                 FeatureInfo[] features = new FeatureInfo[size+1];
3139                 featSet.toArray(features);
3140                 FeatureInfo fi = new FeatureInfo();
3141                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3142                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
3143                 features[size] = fi;
3144                 return features;
3145             }
3146         }
3147         return null;
3148     }
3149
3150     @Override
3151     public boolean hasSystemFeature(String name) {
3152         synchronized (mPackages) {
3153             return mAvailableFeatures.containsKey(name);
3154         }
3155     }
3156
3157     private void checkValidCaller(int uid, int userId) {
3158         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
3159             return;
3160
3161         throw new SecurityException("Caller uid=" + uid
3162                 + " is not privileged to communicate with user=" + userId);
3163     }
3164
3165     @Override
3166     public int checkPermission(String permName, String pkgName, int userId) {
3167         if (!sUserManager.exists(userId)) {
3168             return PackageManager.PERMISSION_DENIED;
3169         }
3170
3171         synchronized (mPackages) {
3172             final PackageParser.Package p = mPackages.get(pkgName);
3173             if (p != null && p.mExtras != null) {
3174                 final PackageSetting ps = (PackageSetting) p.mExtras;
3175                 final PermissionsState permissionsState = ps.getPermissionsState();
3176                 if (permissionsState.hasPermission(permName, userId)) {
3177                     return PackageManager.PERMISSION_GRANTED;
3178                 }
3179                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3180                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3181                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3182                     return PackageManager.PERMISSION_GRANTED;
3183                 }
3184             }
3185         }
3186
3187         return PackageManager.PERMISSION_DENIED;
3188     }
3189
3190     @Override
3191     public int checkUidPermission(String permName, int uid) {
3192         final int userId = UserHandle.getUserId(uid);
3193
3194         if (!sUserManager.exists(userId)) {
3195             return PackageManager.PERMISSION_DENIED;
3196         }
3197
3198         synchronized (mPackages) {
3199             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3200             if (obj != null) {
3201                 final SettingBase ps = (SettingBase) obj;
3202                 final PermissionsState permissionsState = ps.getPermissionsState();
3203                 if (permissionsState.hasPermission(permName, userId)) {
3204                     return PackageManager.PERMISSION_GRANTED;
3205                 }
3206                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3207                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3208                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3209                     return PackageManager.PERMISSION_GRANTED;
3210                 }
3211             } else {
3212                 ArraySet<String> perms = mSystemPermissions.get(uid);
3213                 if (perms != null) {
3214                     if (perms.contains(permName)) {
3215                         return PackageManager.PERMISSION_GRANTED;
3216                     }
3217                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3218                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3219                         return PackageManager.PERMISSION_GRANTED;
3220                     }
3221                 }
3222             }
3223         }
3224
3225         return PackageManager.PERMISSION_DENIED;
3226     }
3227
3228     @Override
3229     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3230         if (UserHandle.getCallingUserId() != userId) {
3231             mContext.enforceCallingPermission(
3232                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3233                     "isPermissionRevokedByPolicy for user " + userId);
3234         }
3235
3236         if (checkPermission(permission, packageName, userId)
3237                 == PackageManager.PERMISSION_GRANTED) {
3238             return false;
3239         }
3240
3241         final long identity = Binder.clearCallingIdentity();
3242         try {
3243             final int flags = getPermissionFlags(permission, packageName, userId);
3244             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3245         } finally {
3246             Binder.restoreCallingIdentity(identity);
3247         }
3248     }
3249
3250     @Override
3251     public String getPermissionControllerPackageName() {
3252         synchronized (mPackages) {
3253             return mRequiredInstallerPackage;
3254         }
3255     }
3256
3257     /**
3258      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3259      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3260      * @param checkShell TODO(yamasani):
3261      * @param message the message to log on security exception
3262      */
3263     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3264             boolean checkShell, String message) {
3265         if (userId < 0) {
3266             throw new IllegalArgumentException("Invalid userId " + userId);
3267         }
3268         if (checkShell) {
3269             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3270         }
3271         if (userId == UserHandle.getUserId(callingUid)) return;
3272         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3273             if (requireFullPermission) {
3274                 mContext.enforceCallingOrSelfPermission(
3275                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3276             } else {
3277                 try {
3278                     mContext.enforceCallingOrSelfPermission(
3279                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3280                 } catch (SecurityException se) {
3281                     mContext.enforceCallingOrSelfPermission(
3282                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3283                 }
3284             }
3285         }
3286     }
3287
3288     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3289         if (callingUid == Process.SHELL_UID) {
3290             if (userHandle >= 0
3291                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
3292                 throw new SecurityException("Shell does not have permission to access user "
3293                         + userHandle);
3294             } else if (userHandle < 0) {
3295                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3296                         + Debug.getCallers(3));
3297             }
3298         }
3299     }
3300
3301     private BasePermission findPermissionTreeLP(String permName) {
3302         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3303             if (permName.startsWith(bp.name) &&
3304                     permName.length() > bp.name.length() &&
3305                     permName.charAt(bp.name.length()) == '.') {
3306                 return bp;
3307             }
3308         }
3309         return null;
3310     }
3311
3312     private BasePermission checkPermissionTreeLP(String permName) {
3313         if (permName != null) {
3314             BasePermission bp = findPermissionTreeLP(permName);
3315             if (bp != null) {
3316                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3317                     return bp;
3318                 }
3319                 throw new SecurityException("Calling uid "
3320                         + Binder.getCallingUid()
3321                         + " is not allowed to add to permission tree "
3322                         + bp.name + " owned by uid " + bp.uid);
3323             }
3324         }
3325         throw new SecurityException("No permission tree found for " + permName);
3326     }
3327
3328     static boolean compareStrings(CharSequence s1, CharSequence s2) {
3329         if (s1 == null) {
3330             return s2 == null;
3331         }
3332         if (s2 == null) {
3333             return false;
3334         }
3335         if (s1.getClass() != s2.getClass()) {
3336             return false;
3337         }
3338         return s1.equals(s2);
3339     }
3340
3341     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3342         if (pi1.icon != pi2.icon) return false;
3343         if (pi1.logo != pi2.logo) return false;
3344         if (pi1.protectionLevel != pi2.protectionLevel) return false;
3345         if (!compareStrings(pi1.name, pi2.name)) return false;
3346         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3347         // We'll take care of setting this one.
3348         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3349         // These are not currently stored in settings.
3350         //if (!compareStrings(pi1.group, pi2.group)) return false;
3351         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3352         //if (pi1.labelRes != pi2.labelRes) return false;
3353         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3354         return true;
3355     }
3356
3357     int permissionInfoFootprint(PermissionInfo info) {
3358         int size = info.name.length();
3359         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3360         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3361         return size;
3362     }
3363
3364     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3365         int size = 0;
3366         for (BasePermission perm : mSettings.mPermissions.values()) {
3367             if (perm.uid == tree.uid) {
3368                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3369             }
3370         }
3371         return size;
3372     }
3373
3374     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3375         // We calculate the max size of permissions defined by this uid and throw
3376         // if that plus the size of 'info' would exceed our stated maximum.
3377         if (tree.uid != Process.SYSTEM_UID) {
3378             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3379             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3380                 throw new SecurityException("Permission tree size cap exceeded");
3381             }
3382         }
3383     }
3384
3385     boolean addPermissionLocked(PermissionInfo info, boolean async) {
3386         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3387             throw new SecurityException("Label must be specified in permission");
3388         }
3389         BasePermission tree = checkPermissionTreeLP(info.name);
3390         BasePermission bp = mSettings.mPermissions.get(info.name);
3391         boolean added = bp == null;
3392         boolean changed = true;
3393         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3394         if (added) {
3395             enforcePermissionCapLocked(info, tree);
3396             bp = new BasePermission(info.name, tree.sourcePackage,
3397                     BasePermission.TYPE_DYNAMIC);
3398         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3399             throw new SecurityException(
3400                     "Not allowed to modify non-dynamic permission "
3401                     + info.name);
3402         } else {
3403             if (bp.protectionLevel == fixedLevel
3404                     && bp.perm.owner.equals(tree.perm.owner)
3405                     && bp.uid == tree.uid
3406                     && comparePermissionInfos(bp.perm.info, info)) {
3407                 changed = false;
3408             }
3409         }
3410         bp.protectionLevel = fixedLevel;
3411         info = new PermissionInfo(info);
3412         info.protectionLevel = fixedLevel;
3413         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3414         bp.perm.info.packageName = tree.perm.info.packageName;
3415         bp.uid = tree.uid;
3416         if (added) {
3417             mSettings.mPermissions.put(info.name, bp);
3418         }
3419         if (changed) {
3420             if (!async) {
3421                 mSettings.writeLPr();
3422             } else {
3423                 scheduleWriteSettingsLocked();
3424             }
3425         }
3426         return added;
3427     }
3428
3429     @Override
3430     public boolean addPermission(PermissionInfo info) {
3431         synchronized (mPackages) {
3432             return addPermissionLocked(info, false);
3433         }
3434     }
3435
3436     @Override
3437     public boolean addPermissionAsync(PermissionInfo info) {
3438         synchronized (mPackages) {
3439             return addPermissionLocked(info, true);
3440         }
3441     }
3442
3443     @Override
3444     public void removePermission(String name) {
3445         synchronized (mPackages) {
3446             checkPermissionTreeLP(name);
3447             BasePermission bp = mSettings.mPermissions.get(name);
3448             if (bp != null) {
3449                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
3450                     throw new SecurityException(
3451                             "Not allowed to modify non-dynamic permission "
3452                             + name);
3453                 }
3454                 mSettings.mPermissions.remove(name);
3455                 mSettings.writeLPr();
3456             }
3457         }
3458     }
3459
3460     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
3461             BasePermission bp) {
3462         int index = pkg.requestedPermissions.indexOf(bp.name);
3463         if (index == -1) {
3464             throw new SecurityException("Package " + pkg.packageName
3465                     + " has not requested permission " + bp.name);
3466         }
3467         if (!bp.isRuntime() && !bp.isDevelopment()) {
3468             throw new SecurityException("Permission " + bp.name
3469                     + " is not a changeable permission type");
3470         }
3471     }
3472
3473     @Override
3474     public void grantRuntimePermission(String packageName, String name, final int userId) {
3475         if (!sUserManager.exists(userId)) {
3476             Log.e(TAG, "No such user:" + userId);
3477             return;
3478         }
3479
3480         mContext.enforceCallingOrSelfPermission(
3481                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
3482                 "grantRuntimePermission");
3483
3484         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3485                 "grantRuntimePermission");
3486
3487         final int uid;
3488         final SettingBase sb;
3489
3490         synchronized (mPackages) {
3491             final PackageParser.Package pkg = mPackages.get(packageName);
3492             if (pkg == null) {
3493                 throw new IllegalArgumentException("Unknown package: " + packageName);
3494             }
3495
3496             final BasePermission bp = mSettings.mPermissions.get(name);
3497             if (bp == null) {
3498                 throw new IllegalArgumentException("Unknown permission: " + name);
3499             }
3500
3501             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3502
3503             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
3504             sb = (SettingBase) pkg.mExtras;
3505             if (sb == null) {
3506                 throw new IllegalArgumentException("Unknown package: " + packageName);
3507             }
3508
3509             final PermissionsState permissionsState = sb.getPermissionsState();
3510
3511             final int flags = permissionsState.getPermissionFlags(name, userId);
3512             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3513                 throw new SecurityException("Cannot grant system fixed permission: "
3514                         + name + " for package: " + packageName);
3515             }
3516
3517             if (bp.isDevelopment()) {
3518                 // Development permissions must be handled specially, since they are not
3519                 // normal runtime permissions.  For now they apply to all users.
3520                 if (permissionsState.grantInstallPermission(bp) !=
3521                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
3522                     scheduleWriteSettingsLocked();
3523                 }
3524                 return;
3525             }
3526
3527             final int result = permissionsState.grantRuntimePermission(bp, userId);
3528             switch (result) {
3529                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3530                     return;
3531                 }
3532
3533                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3534                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3535                     mHandler.post(new Runnable() {
3536                         @Override
3537                         public void run() {
3538                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
3539                         }
3540                     });
3541                 }
3542                 break;
3543             }
3544
3545             mOnPermissionChangeListeners.onPermissionsChanged(uid);
3546
3547             // Not critical if that is lost - app has to request again.
3548             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3549         }
3550
3551         // Only need to do this if user is initialized. Otherwise it's a new user
3552         // and there are no processes running as the user yet and there's no need
3553         // to make an expensive call to remount processes for the changed permissions.
3554         if (READ_EXTERNAL_STORAGE.equals(name)
3555                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
3556             final long token = Binder.clearCallingIdentity();
3557             try {
3558                 if (sUserManager.isInitialized(userId)) {
3559                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3560                             MountServiceInternal.class);
3561                     mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
3562                 }
3563             } finally {
3564                 Binder.restoreCallingIdentity(token);
3565             }
3566         }
3567     }
3568
3569     @Override
3570     public void revokeRuntimePermission(String packageName, String name, int userId) {
3571         if (!sUserManager.exists(userId)) {
3572             Log.e(TAG, "No such user:" + userId);
3573             return;
3574         }
3575
3576         mContext.enforceCallingOrSelfPermission(
3577                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3578                 "revokeRuntimePermission");
3579
3580         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3581                 "revokeRuntimePermission");
3582
3583         final int appId;
3584
3585         synchronized (mPackages) {
3586             final PackageParser.Package pkg = mPackages.get(packageName);
3587             if (pkg == null) {
3588                 throw new IllegalArgumentException("Unknown package: " + packageName);
3589             }
3590
3591             final BasePermission bp = mSettings.mPermissions.get(name);
3592             if (bp == null) {
3593                 throw new IllegalArgumentException("Unknown permission: " + name);
3594             }
3595
3596             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3597
3598             SettingBase sb = (SettingBase) pkg.mExtras;
3599             if (sb == null) {
3600                 throw new IllegalArgumentException("Unknown package: " + packageName);
3601             }
3602
3603             final PermissionsState permissionsState = sb.getPermissionsState();
3604
3605             final int flags = permissionsState.getPermissionFlags(name, userId);
3606             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3607                 throw new SecurityException("Cannot revoke system fixed permission: "
3608                         + name + " for package: " + packageName);
3609             }
3610
3611             if (bp.isDevelopment()) {
3612                 // Development permissions must be handled specially, since they are not
3613                 // normal runtime permissions.  For now they apply to all users.
3614                 if (permissionsState.revokeInstallPermission(bp) !=
3615                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
3616                     scheduleWriteSettingsLocked();
3617                 }
3618                 return;
3619             }
3620
3621             if (permissionsState.revokeRuntimePermission(bp, userId) ==
3622                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
3623                 return;
3624             }
3625
3626             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
3627
3628             // Critical, after this call app should never have the permission.
3629             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
3630
3631             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3632         }
3633
3634         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
3635     }
3636
3637     @Override
3638     public void resetRuntimePermissions() {
3639         mContext.enforceCallingOrSelfPermission(
3640                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3641                 "revokeRuntimePermission");
3642
3643         int callingUid = Binder.getCallingUid();
3644         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3645             mContext.enforceCallingOrSelfPermission(
3646                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3647                     "resetRuntimePermissions");
3648         }
3649
3650         synchronized (mPackages) {
3651             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
3652             for (int userId : UserManagerService.getInstance().getUserIds()) {
3653                 final int packageCount = mPackages.size();
3654                 for (int i = 0; i < packageCount; i++) {
3655                     PackageParser.Package pkg = mPackages.valueAt(i);
3656                     if (!(pkg.mExtras instanceof PackageSetting)) {
3657                         continue;
3658                     }
3659                     PackageSetting ps = (PackageSetting) pkg.mExtras;
3660                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
3661                 }
3662             }
3663         }
3664     }
3665
3666     @Override
3667     public int getPermissionFlags(String name, String packageName, int userId) {
3668         if (!sUserManager.exists(userId)) {
3669             return 0;
3670         }
3671
3672         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
3673
3674         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3675                 "getPermissionFlags");
3676
3677         synchronized (mPackages) {
3678             final PackageParser.Package pkg = mPackages.get(packageName);
3679             if (pkg == null) {
3680                 throw new IllegalArgumentException("Unknown package: " + packageName);
3681             }
3682
3683             final BasePermission bp = mSettings.mPermissions.get(name);
3684             if (bp == null) {
3685                 throw new IllegalArgumentException("Unknown permission: " + name);
3686             }
3687
3688             SettingBase sb = (SettingBase) pkg.mExtras;
3689             if (sb == null) {
3690                 throw new IllegalArgumentException("Unknown package: " + packageName);
3691             }
3692
3693             PermissionsState permissionsState = sb.getPermissionsState();
3694             return permissionsState.getPermissionFlags(name, userId);
3695         }
3696     }
3697
3698     @Override
3699     public void updatePermissionFlags(String name, String packageName, int flagMask,
3700             int flagValues, int userId) {
3701         if (!sUserManager.exists(userId)) {
3702             return;
3703         }
3704
3705         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
3706
3707         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3708                 "updatePermissionFlags");
3709
3710         // Only the system can change these flags and nothing else.
3711         if (getCallingUid() != Process.SYSTEM_UID) {
3712             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3713             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3714             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3715             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3716         }
3717
3718         synchronized (mPackages) {
3719             final PackageParser.Package pkg = mPackages.get(packageName);
3720             if (pkg == null) {
3721                 throw new IllegalArgumentException("Unknown package: " + packageName);
3722             }
3723
3724             final BasePermission bp = mSettings.mPermissions.get(name);
3725             if (bp == null) {
3726                 throw new IllegalArgumentException("Unknown permission: " + name);
3727             }
3728
3729             SettingBase sb = (SettingBase) pkg.mExtras;
3730             if (sb == null) {
3731                 throw new IllegalArgumentException("Unknown package: " + packageName);
3732             }
3733
3734             PermissionsState permissionsState = sb.getPermissionsState();
3735
3736             // Only the package manager can change flags for system component permissions.
3737             final int flags = permissionsState.getPermissionFlags(bp.name, userId);
3738             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3739                 return;
3740             }
3741
3742             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
3743
3744             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
3745                 // Install and runtime permissions are stored in different places,
3746                 // so figure out what permission changed and persist the change.
3747                 if (permissionsState.getInstallPermissionState(name) != null) {
3748                     scheduleWriteSettingsLocked();
3749                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
3750                         || hadState) {
3751                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3752                 }
3753             }
3754         }
3755     }
3756
3757     /**
3758      * Update the permission flags for all packages and runtime permissions of a user in order
3759      * to allow device or profile owner to remove POLICY_FIXED.
3760      */
3761     @Override
3762     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
3763         if (!sUserManager.exists(userId)) {
3764             return;
3765         }
3766
3767         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
3768
3769         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3770                 "updatePermissionFlagsForAllApps");
3771
3772         // Only the system can change system fixed flags.
3773         if (getCallingUid() != Process.SYSTEM_UID) {
3774             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3775             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3776         }
3777
3778         synchronized (mPackages) {
3779             boolean changed = false;
3780             final int packageCount = mPackages.size();
3781             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
3782                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
3783                 SettingBase sb = (SettingBase) pkg.mExtras;
3784                 if (sb == null) {
3785                     continue;
3786                 }
3787                 PermissionsState permissionsState = sb.getPermissionsState();
3788                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
3789                         userId, flagMask, flagValues);
3790             }
3791             if (changed) {
3792                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3793             }
3794         }
3795     }
3796
3797     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3798         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
3799                 != PackageManager.PERMISSION_GRANTED
3800             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
3801                 != PackageManager.PERMISSION_GRANTED) {
3802             throw new SecurityException(message + " requires "
3803                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
3804                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
3805         }
3806     }
3807
3808     @Override
3809     public boolean shouldShowRequestPermissionRationale(String permissionName,
3810             String packageName, int userId) {
3811         if (UserHandle.getCallingUserId() != userId) {
3812             mContext.enforceCallingPermission(
3813                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3814                     "canShowRequestPermissionRationale for user " + userId);
3815         }
3816
3817         final int uid = getPackageUid(packageName, userId);
3818         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
3819             return false;
3820         }
3821
3822         if (checkPermission(permissionName, packageName, userId)
3823                 == PackageManager.PERMISSION_GRANTED) {
3824             return false;
3825         }
3826
3827         final int flags;
3828
3829         final long identity = Binder.clearCallingIdentity();
3830         try {
3831             flags = getPermissionFlags(permissionName,
3832                     packageName, userId);
3833         } finally {
3834             Binder.restoreCallingIdentity(identity);
3835         }
3836
3837         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3838                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
3839                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
3840
3841         if ((flags & fixedFlags) != 0) {
3842             return false;
3843         }
3844
3845         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
3846     }
3847
3848     @Override
3849     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
3850         mContext.enforceCallingOrSelfPermission(
3851                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
3852                 "addOnPermissionsChangeListener");
3853
3854         synchronized (mPackages) {
3855             mOnPermissionChangeListeners.addListenerLocked(listener);
3856         }
3857     }
3858
3859     @Override
3860     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
3861         synchronized (mPackages) {
3862             mOnPermissionChangeListeners.removeListenerLocked(listener);
3863         }
3864     }
3865
3866     @Override
3867     public boolean isProtectedBroadcast(String actionName) {
3868         synchronized (mPackages) {
3869             return mProtectedBroadcasts.contains(actionName);
3870         }
3871     }
3872
3873     @Override
3874     public int checkSignatures(String pkg1, String pkg2) {
3875         synchronized (mPackages) {
3876             final PackageParser.Package p1 = mPackages.get(pkg1);
3877             final PackageParser.Package p2 = mPackages.get(pkg2);
3878             if (p1 == null || p1.mExtras == null
3879                     || p2 == null || p2.mExtras == null) {
3880                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3881             }
3882             return compareSignatures(p1.mSignatures, p2.mSignatures);
3883         }
3884     }
3885
3886     @Override
3887     public int checkUidSignatures(int uid1, int uid2) {
3888         // Map to base uids.
3889         uid1 = UserHandle.getAppId(uid1);
3890         uid2 = UserHandle.getAppId(uid2);
3891         // reader
3892         synchronized (mPackages) {
3893             Signature[] s1;
3894             Signature[] s2;
3895             Object obj = mSettings.getUserIdLPr(uid1);
3896             if (obj != null) {
3897                 if (obj instanceof SharedUserSetting) {
3898                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
3899                 } else if (obj instanceof PackageSetting) {
3900                     s1 = ((PackageSetting)obj).signatures.mSignatures;
3901                 } else {
3902                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3903                 }
3904             } else {
3905                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3906             }
3907             obj = mSettings.getUserIdLPr(uid2);
3908             if (obj != null) {
3909                 if (obj instanceof SharedUserSetting) {
3910                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
3911                 } else if (obj instanceof PackageSetting) {
3912                     s2 = ((PackageSetting)obj).signatures.mSignatures;
3913                 } else {
3914                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3915                 }
3916             } else {
3917                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3918             }
3919             return compareSignatures(s1, s2);
3920         }
3921     }
3922
3923     private void killUid(int appId, int userId, String reason) {
3924         final long identity = Binder.clearCallingIdentity();
3925         try {
3926             IActivityManager am = ActivityManagerNative.getDefault();
3927             if (am != null) {
3928                 try {
3929                     am.killUid(appId, userId, reason);
3930                 } catch (RemoteException e) {
3931                     /* ignore - same process */
3932                 }
3933             }
3934         } finally {
3935             Binder.restoreCallingIdentity(identity);
3936         }
3937     }
3938
3939     /**
3940      * Compares two sets of signatures. Returns:
3941      * <br />
3942      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
3943      * <br />
3944      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
3945      * <br />
3946      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
3947      * <br />
3948      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
3949      * <br />
3950      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
3951      */
3952     static int compareSignatures(Signature[] s1, Signature[] s2) {
3953         if (s1 == null) {
3954             return s2 == null
3955                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
3956                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
3957         }
3958
3959         if (s2 == null) {
3960             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
3961         }
3962
3963         if (s1.length != s2.length) {
3964             return PackageManager.SIGNATURE_NO_MATCH;
3965         }
3966
3967         // Since both signature sets are of size 1, we can compare without HashSets.
3968         if (s1.length == 1) {
3969             return s1[0].equals(s2[0]) ?
3970                     PackageManager.SIGNATURE_MATCH :
3971                     PackageManager.SIGNATURE_NO_MATCH;
3972         }
3973
3974         ArraySet<Signature> set1 = new ArraySet<Signature>();
3975         for (Signature sig : s1) {
3976             set1.add(sig);
3977         }
3978         ArraySet<Signature> set2 = new ArraySet<Signature>();
3979         for (Signature sig : s2) {
3980             set2.add(sig);
3981         }
3982         // Make sure s2 contains all signatures in s1.
3983         if (set1.equals(set2)) {
3984             return PackageManager.SIGNATURE_MATCH;
3985         }
3986         return PackageManager.SIGNATURE_NO_MATCH;
3987     }
3988
3989     /**
3990      * If the database version for this type of package (internal storage or
3991      * external storage) is less than the version where package signatures
3992      * were updated, return true.
3993      */
3994     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
3995         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
3996         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
3997     }
3998
3999     /**
4000      * Used for backward compatibility to make sure any packages with
4001      * certificate chains get upgraded to the new style. {@code existingSigs}
4002      * will be in the old format (since they were stored on disk from before the
4003      * system upgrade) and {@code scannedSigs} will be in the newer format.
4004      */
4005     private int compareSignaturesCompat(PackageSignatures existingSigs,
4006             PackageParser.Package scannedPkg) {
4007         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4008             return PackageManager.SIGNATURE_NO_MATCH;
4009         }
4010
4011         ArraySet<Signature> existingSet = new ArraySet<Signature>();
4012         for (Signature sig : existingSigs.mSignatures) {
4013             existingSet.add(sig);
4014         }
4015         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4016         for (Signature sig : scannedPkg.mSignatures) {
4017             try {
4018                 Signature[] chainSignatures = sig.getChainSignatures();
4019                 for (Signature chainSig : chainSignatures) {
4020                     scannedCompatSet.add(chainSig);
4021                 }
4022             } catch (CertificateEncodingException e) {
4023                 scannedCompatSet.add(sig);
4024             }
4025         }
4026         /*
4027          * Make sure the expanded scanned set contains all signatures in the
4028          * existing one.
4029          */
4030         if (scannedCompatSet.equals(existingSet)) {
4031             // Migrate the old signatures to the new scheme.
4032             existingSigs.assignSignatures(scannedPkg.mSignatures);
4033             // The new KeySets will be re-added later in the scanning process.
4034             synchronized (mPackages) {
4035                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4036             }
4037             return PackageManager.SIGNATURE_MATCH;
4038         }
4039         return PackageManager.SIGNATURE_NO_MATCH;
4040     }
4041
4042     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4043         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4044         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4045     }
4046
4047     private int compareSignaturesRecover(PackageSignatures existingSigs,
4048             PackageParser.Package scannedPkg) {
4049         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4050             return PackageManager.SIGNATURE_NO_MATCH;
4051         }
4052
4053         String msg = null;
4054         try {
4055             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4056                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4057                         + scannedPkg.packageName);
4058                 return PackageManager.SIGNATURE_MATCH;
4059             }
4060         } catch (CertificateException e) {
4061             msg = e.getMessage();
4062         }
4063
4064         logCriticalInfo(Log.INFO,
4065                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4066         return PackageManager.SIGNATURE_NO_MATCH;
4067     }
4068
4069     @Override
4070     public String[] getPackagesForUid(int uid) {
4071         uid = UserHandle.getAppId(uid);
4072         // reader
4073         synchronized (mPackages) {
4074             Object obj = mSettings.getUserIdLPr(uid);
4075             if (obj instanceof SharedUserSetting) {
4076                 final SharedUserSetting sus = (SharedUserSetting) obj;
4077                 final int N = sus.packages.size();
4078                 final String[] res = new String[N];
4079                 final Iterator<PackageSetting> it = sus.packages.iterator();
4080                 int i = 0;
4081                 while (it.hasNext()) {
4082                     res[i++] = it.next().name;
4083                 }
4084                 return res;
4085             } else if (obj instanceof PackageSetting) {
4086                 final PackageSetting ps = (PackageSetting) obj;
4087                 return new String[] { ps.name };
4088             }
4089         }
4090         return null;
4091     }
4092
4093     @Override
4094     public String getNameForUid(int uid) {
4095         // reader
4096         synchronized (mPackages) {
4097             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4098             if (obj instanceof SharedUserSetting) {
4099                 final SharedUserSetting sus = (SharedUserSetting) obj;
4100                 return sus.name + ":" + sus.userId;
4101             } else if (obj instanceof PackageSetting) {
4102                 final PackageSetting ps = (PackageSetting) obj;
4103                 return ps.name;
4104             }
4105         }
4106         return null;
4107     }
4108
4109     @Override
4110     public int getUidForSharedUser(String sharedUserName) {
4111         if(sharedUserName == null) {
4112             return -1;
4113         }
4114         // reader
4115         synchronized (mPackages) {
4116             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4117             if (suid == null) {
4118                 return -1;
4119             }
4120             return suid.userId;
4121         }
4122     }
4123
4124     @Override
4125     public int getFlagsForUid(int uid) {
4126         synchronized (mPackages) {
4127             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4128             if (obj instanceof SharedUserSetting) {
4129                 final SharedUserSetting sus = (SharedUserSetting) obj;
4130                 return sus.pkgFlags;
4131             } else if (obj instanceof PackageSetting) {
4132                 final PackageSetting ps = (PackageSetting) obj;
4133                 return ps.pkgFlags;
4134             }
4135         }
4136         return 0;
4137     }
4138
4139     @Override
4140     public int getPrivateFlagsForUid(int uid) {
4141         synchronized (mPackages) {
4142             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4143             if (obj instanceof SharedUserSetting) {
4144                 final SharedUserSetting sus = (SharedUserSetting) obj;
4145                 return sus.pkgPrivateFlags;
4146             } else if (obj instanceof PackageSetting) {
4147                 final PackageSetting ps = (PackageSetting) obj;
4148                 return ps.pkgPrivateFlags;
4149             }
4150         }
4151         return 0;
4152     }
4153
4154     @Override
4155     public boolean isUidPrivileged(int uid) {
4156         uid = UserHandle.getAppId(uid);
4157         // reader
4158         synchronized (mPackages) {
4159             Object obj = mSettings.getUserIdLPr(uid);
4160             if (obj instanceof SharedUserSetting) {
4161                 final SharedUserSetting sus = (SharedUserSetting) obj;
4162                 final Iterator<PackageSetting> it = sus.packages.iterator();
4163                 while (it.hasNext()) {
4164                     if (it.next().isPrivileged()) {
4165                         return true;
4166                     }
4167                 }
4168             } else if (obj instanceof PackageSetting) {
4169                 final PackageSetting ps = (PackageSetting) obj;
4170                 return ps.isPrivileged();
4171             }
4172         }
4173         return false;
4174     }
4175
4176     @Override
4177     public String[] getAppOpPermissionPackages(String permissionName) {
4178         synchronized (mPackages) {
4179             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4180             if (pkgs == null) {
4181                 return null;
4182             }
4183             return pkgs.toArray(new String[pkgs.size()]);
4184         }
4185     }
4186
4187     @Override
4188     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4189             int flags, int userId) {
4190         if (!sUserManager.exists(userId)) return null;
4191         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
4192         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4193         return chooseBestActivity(intent, resolvedType, flags, query, userId);
4194     }
4195
4196     @Override
4197     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4198             IntentFilter filter, int match, ComponentName activity) {
4199         final int userId = UserHandle.getCallingUserId();
4200         if (DEBUG_PREFERRED) {
4201             Log.v(TAG, "setLastChosenActivity intent=" + intent
4202                 + " resolvedType=" + resolvedType
4203                 + " flags=" + flags
4204                 + " filter=" + filter
4205                 + " match=" + match
4206                 + " activity=" + activity);
4207             filter.dump(new PrintStreamPrinter(System.out), "    ");
4208         }
4209         intent.setComponent(null);
4210         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4211         // Find any earlier preferred or last chosen entries and nuke them
4212         findPreferredActivity(intent, resolvedType,
4213                 flags, query, 0, false, true, false, userId);
4214         // Add the new activity as the last chosen for this filter
4215         addPreferredActivityInternal(filter, match, null, activity, false, userId,
4216                 "Setting last chosen");
4217     }
4218
4219     @Override
4220     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4221         final int userId = UserHandle.getCallingUserId();
4222         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4223         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4224         return findPreferredActivity(intent, resolvedType, flags, query, 0,
4225                 false, false, false, userId);
4226     }
4227
4228     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
4229             int flags, List<ResolveInfo> query, int userId) {
4230         if (query != null) {
4231             final int N = query.size();
4232             if (N == 1) {
4233                 return query.get(0);
4234             } else if (N > 1) {
4235                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4236                 // If there is more than one activity with the same priority,
4237                 // then let the user decide between them.
4238                 ResolveInfo r0 = query.get(0);
4239                 ResolveInfo r1 = query.get(1);
4240                 if (DEBUG_INTENT_MATCHING || debug) {
4241                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
4242                             + r1.activityInfo.name + "=" + r1.priority);
4243                 }
4244                 // If the first activity has a higher priority, or a different
4245                 // default, then it is always desireable to pick it.
4246                 if (r0.priority != r1.priority
4247                         || r0.preferredOrder != r1.preferredOrder
4248                         || r0.isDefault != r1.isDefault) {
4249                     return query.get(0);
4250                 }
4251                 // If we have saved a preference for a preferred activity for
4252                 // this Intent, use that.
4253                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
4254                         flags, query, r0.priority, true, false, debug, userId);
4255                 if (ri != null) {
4256                     return ri;
4257                 }
4258                 ri = new ResolveInfo(mResolveInfo);
4259                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
4260                 ri.activityInfo.applicationInfo = new ApplicationInfo(
4261                         ri.activityInfo.applicationInfo);
4262                 if (userId != 0) {
4263                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
4264                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
4265                 }
4266                 // Make sure that the resolver is displayable in car mode
4267                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
4268                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
4269                 return ri;
4270             }
4271         }
4272         return null;
4273     }
4274
4275     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
4276             int flags, List<ResolveInfo> query, boolean debug, int userId) {
4277         final int N = query.size();
4278         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
4279                 .get(userId);
4280         // Get the list of persistent preferred activities that handle the intent
4281         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
4282         List<PersistentPreferredActivity> pprefs = ppir != null
4283                 ? ppir.queryIntent(intent, resolvedType,
4284                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4285                 : null;
4286         if (pprefs != null && pprefs.size() > 0) {
4287             final int M = pprefs.size();
4288             for (int i=0; i<M; i++) {
4289                 final PersistentPreferredActivity ppa = pprefs.get(i);
4290                 if (DEBUG_PREFERRED || debug) {
4291                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4292                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4293                             + "\n  component=" + ppa.mComponent);
4294                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4295                 }
4296                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4297                         flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
4298                 if (DEBUG_PREFERRED || debug) {
4299                     Slog.v(TAG, "Found persistent preferred activity:");
4300                     if (ai != null) {
4301                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4302                     } else {
4303                         Slog.v(TAG, "  null");
4304                     }
4305                 }
4306                 if (ai == null) {
4307                     // This previously registered persistent preferred activity
4308                     // component is no longer known. Ignore it and do NOT remove it.
4309                     continue;
4310                 }
4311                 for (int j=0; j<N; j++) {
4312                     final ResolveInfo ri = query.get(j);
4313                     if (!ri.activityInfo.applicationInfo.packageName
4314                             .equals(ai.applicationInfo.packageName)) {
4315                         continue;
4316                     }
4317                     if (!ri.activityInfo.name.equals(ai.name)) {
4318                         continue;
4319                     }
4320                     //  Found a persistent preference that can handle the intent.
4321                     if (DEBUG_PREFERRED || debug) {
4322                         Slog.v(TAG, "Returning persistent preferred activity: " +
4323                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4324                     }
4325                     return ri;
4326                 }
4327             }
4328         }
4329         return null;
4330     }
4331
4332     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
4333             List<ResolveInfo> query, int priority, boolean always,
4334             boolean removeMatches, boolean debug, int userId) {
4335         if (!sUserManager.exists(userId)) return null;
4336         // writer
4337         synchronized (mPackages) {
4338             if (intent.getSelector() != null) {
4339                 intent = intent.getSelector();
4340             }
4341             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4342
4343             // Try to find a matching persistent preferred activity.
4344             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
4345                     debug, userId);
4346
4347             // If a persistent preferred activity matched, use it.
4348             if (pri != null) {
4349                 return pri;
4350             }
4351
4352             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
4353             // Get the list of preferred activities that handle the intent
4354             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4355             List<PreferredActivity> prefs = pir != null
4356                     ? pir.queryIntent(intent, resolvedType,
4357                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4358                     : null;
4359             if (prefs != null && prefs.size() > 0) {
4360                 boolean changed = false;
4361                 try {
4362                     // First figure out how good the original match set is.
4363                     // We will only allow preferred activities that came
4364                     // from the same match quality.
4365                     int match = 0;
4366
4367                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4368
4369                     final int N = query.size();
4370                     for (int j=0; j<N; j++) {
4371                         final ResolveInfo ri = query.get(j);
4372                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
4373                                 + ": 0x" + Integer.toHexString(match));
4374                         if (ri.match > match) {
4375                             match = ri.match;
4376                         }
4377                     }
4378
4379                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
4380                             + Integer.toHexString(match));
4381
4382                     match &= IntentFilter.MATCH_CATEGORY_MASK;
4383                     final int M = prefs.size();
4384                     for (int i=0; i<M; i++) {
4385                         final PreferredActivity pa = prefs.get(i);
4386                         if (DEBUG_PREFERRED || debug) {
4387                             Slog.v(TAG, "Checking PreferredActivity ds="
4388                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4389                                     + "\n  component=" + pa.mPref.mComponent);
4390                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4391                         }
4392                         if (pa.mPref.mMatch != match) {
4393                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
4394                                     + Integer.toHexString(pa.mPref.mMatch));
4395                             continue;
4396                         }
4397                         // If it's not an "always" type preferred activity and that's what we're
4398                         // looking for, skip it.
4399                         if (always && !pa.mPref.mAlways) {
4400                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4401                             continue;
4402                         }
4403                         final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
4404                                 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
4405                         if (DEBUG_PREFERRED || debug) {
4406                             Slog.v(TAG, "Found preferred activity:");
4407                             if (ai != null) {
4408                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4409                             } else {
4410                                 Slog.v(TAG, "  null");
4411                             }
4412                         }
4413                         if (ai == null) {
4414                             // This previously registered preferred activity
4415                             // component is no longer known.  Most likely an update
4416                             // to the app was installed and in the new version this
4417                             // component no longer exists.  Clean it up by removing
4418                             // it from the preferred activities list, and skip it.
4419                             Slog.w(TAG, "Removing dangling preferred activity: "
4420                                     + pa.mPref.mComponent);
4421                             pir.removeFilter(pa);
4422                             changed = true;
4423                             continue;
4424                         }
4425                         for (int j=0; j<N; j++) {
4426                             final ResolveInfo ri = query.get(j);
4427                             if (!ri.activityInfo.applicationInfo.packageName
4428                                     .equals(ai.applicationInfo.packageName)) {
4429                                 continue;
4430                             }
4431                             if (!ri.activityInfo.name.equals(ai.name)) {
4432                                 continue;
4433                             }
4434
4435                             if (removeMatches) {
4436                                 pir.removeFilter(pa);
4437                                 changed = true;
4438                                 if (DEBUG_PREFERRED) {
4439                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
4440                                 }
4441                                 break;
4442                             }
4443
4444                             // Okay we found a previously set preferred or last chosen app.
4445                             // If the result set is different from when this
4446                             // was created, we need to clear it and re-ask the
4447                             // user their preference, if we're looking for an "always" type entry.
4448                             if (always && !pa.mPref.sameSet(query)) {
4449                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
4450                                         + intent + " type " + resolvedType);
4451                                 if (DEBUG_PREFERRED) {
4452                                     Slog.v(TAG, "Removing preferred activity since set changed "
4453                                             + pa.mPref.mComponent);
4454                                 }
4455                                 pir.removeFilter(pa);
4456                                 // Re-add the filter as a "last chosen" entry (!always)
4457                                 PreferredActivity lastChosen = new PreferredActivity(
4458                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
4459                                 pir.addFilter(lastChosen);
4460                                 changed = true;
4461                                 return null;
4462                             }
4463
4464                             // Yay! Either the set matched or we're looking for the last chosen
4465                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
4466                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4467                             return ri;
4468                         }
4469                     }
4470                 } finally {
4471                     if (changed) {
4472                         if (DEBUG_PREFERRED) {
4473                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
4474                         }
4475                         scheduleWritePackageRestrictionsLocked(userId);
4476                     }
4477                 }
4478             }
4479         }
4480         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
4481         return null;
4482     }
4483
4484     /*
4485      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
4486      */
4487     @Override
4488     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
4489             int targetUserId) {
4490         mContext.enforceCallingOrSelfPermission(
4491                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
4492         List<CrossProfileIntentFilter> matches =
4493                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
4494         if (matches != null) {
4495             int size = matches.size();
4496             for (int i = 0; i < size; i++) {
4497                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
4498             }
4499         }
4500         if (hasWebURI(intent)) {
4501             // cross-profile app linking works only towards the parent.
4502             final UserInfo parent = getProfileParent(sourceUserId);
4503             synchronized(mPackages) {
4504                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
4505                         intent, resolvedType, 0, sourceUserId, parent.id);
4506                 return xpDomainInfo != null;
4507             }
4508         }
4509         return false;
4510     }
4511
4512     private UserInfo getProfileParent(int userId) {
4513         final long identity = Binder.clearCallingIdentity();
4514         try {
4515             return sUserManager.getProfileParent(userId);
4516         } finally {
4517             Binder.restoreCallingIdentity(identity);
4518         }
4519     }
4520
4521     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
4522             String resolvedType, int userId) {
4523         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
4524         if (resolver != null) {
4525             return resolver.queryIntent(intent, resolvedType, false, userId);
4526         }
4527         return null;
4528     }
4529
4530     @Override
4531     public List<ResolveInfo> queryIntentActivities(Intent intent,
4532             String resolvedType, int flags, int userId) {
4533         if (!sUserManager.exists(userId)) return Collections.emptyList();
4534         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
4535         ComponentName comp = intent.getComponent();
4536         if (comp == null) {
4537             if (intent.getSelector() != null) {
4538                 intent = intent.getSelector();
4539                 comp = intent.getComponent();
4540             }
4541         }
4542
4543         if (comp != null) {
4544             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4545             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
4546             if (ai != null) {
4547                 final ResolveInfo ri = new ResolveInfo();
4548                 ri.activityInfo = ai;
4549                 list.add(ri);
4550             }
4551             return list;
4552         }
4553
4554         // reader
4555         synchronized (mPackages) {
4556             final String pkgName = intent.getPackage();
4557             if (pkgName == null) {
4558                 List<CrossProfileIntentFilter> matchingFilters =
4559                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
4560                 // Check for results that need to skip the current profile.
4561                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
4562                         resolvedType, flags, userId);
4563                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4564                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
4565                     result.add(xpResolveInfo);
4566                     return filterIfNotPrimaryUser(result, userId);
4567                 }
4568
4569                 // Check for results in the current profile.
4570                 List<ResolveInfo> result = mActivities.queryIntent(
4571                         intent, resolvedType, flags, userId);
4572
4573                 // Check for cross profile results.
4574                 xpResolveInfo = queryCrossProfileIntents(
4575                         matchingFilters, intent, resolvedType, flags, userId);
4576                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4577                     result.add(xpResolveInfo);
4578                     Collections.sort(result, mResolvePrioritySorter);
4579                 }
4580                 result = filterIfNotPrimaryUser(result, userId);
4581                 if (hasWebURI(intent)) {
4582                     CrossProfileDomainInfo xpDomainInfo = null;
4583                     final UserInfo parent = getProfileParent(userId);
4584                     if (parent != null) {
4585                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
4586                                 flags, userId, parent.id);
4587                     }
4588                     if (xpDomainInfo != null) {
4589                         if (xpResolveInfo != null) {
4590                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
4591                             // in the result.
4592                             result.remove(xpResolveInfo);
4593                         }
4594                         if (result.size() == 0) {
4595                             result.add(xpDomainInfo.resolveInfo);
4596                             return result;
4597                         }
4598                     } else if (result.size() <= 1) {
4599                         return result;
4600                     }
4601                     result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
4602                             xpDomainInfo, userId);
4603                     Collections.sort(result, mResolvePrioritySorter);
4604                 }
4605                 return result;
4606             }
4607             final PackageParser.Package pkg = mPackages.get(pkgName);
4608             if (pkg != null) {
4609                 return filterIfNotPrimaryUser(
4610                         mActivities.queryIntentForPackage(
4611                                 intent, resolvedType, flags, pkg.activities, userId),
4612                         userId);
4613             }
4614             return new ArrayList<ResolveInfo>();
4615         }
4616     }
4617
4618     private static class CrossProfileDomainInfo {
4619         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
4620         ResolveInfo resolveInfo;
4621         /* Best domain verification status of the activities found in the other profile */
4622         int bestDomainVerificationStatus;
4623     }
4624
4625     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
4626             String resolvedType, int flags, int sourceUserId, int parentUserId) {
4627         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
4628                 sourceUserId)) {
4629             return null;
4630         }
4631         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4632                 resolvedType, flags, parentUserId);
4633
4634         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
4635             return null;
4636         }
4637         CrossProfileDomainInfo result = null;
4638         int size = resultTargetUser.size();
4639         for (int i = 0; i < size; i++) {
4640             ResolveInfo riTargetUser = resultTargetUser.get(i);
4641             // Intent filter verification is only for filters that specify a host. So don't return
4642             // those that handle all web uris.
4643             if (riTargetUser.handleAllWebDataURI) {
4644                 continue;
4645             }
4646             String packageName = riTargetUser.activityInfo.packageName;
4647             PackageSetting ps = mSettings.mPackages.get(packageName);
4648             if (ps == null) {
4649                 continue;
4650             }
4651             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
4652             int status = (int)(verificationState >> 32);
4653             if (result == null) {
4654                 result = new CrossProfileDomainInfo();
4655                 result.resolveInfo =
4656                         createForwardingResolveInfo(new IntentFilter(), sourceUserId, parentUserId);
4657                 result.bestDomainVerificationStatus = status;
4658             } else {
4659                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
4660                         result.bestDomainVerificationStatus);
4661             }
4662         }
4663         // Don't consider matches with status NEVER across profiles.
4664         if (result != null && result.bestDomainVerificationStatus
4665                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4666             return null;
4667         }
4668         return result;
4669     }
4670
4671     /**
4672      * Verification statuses are ordered from the worse to the best, except for
4673      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
4674      */
4675     private int bestDomainVerificationStatus(int status1, int status2) {
4676         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4677             return status2;
4678         }
4679         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4680             return status1;
4681         }
4682         return (int) MathUtils.max(status1, status2);
4683     }
4684
4685     private boolean isUserEnabled(int userId) {
4686         long callingId = Binder.clearCallingIdentity();
4687         try {
4688             UserInfo userInfo = sUserManager.getUserInfo(userId);
4689             return userInfo != null && userInfo.isEnabled();
4690         } finally {
4691             Binder.restoreCallingIdentity(callingId);
4692         }
4693     }
4694
4695     /**
4696      * Filter out activities with primaryUserOnly flag set, when current user is not the owner.
4697      *
4698      * @return filtered list
4699      */
4700     private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) {
4701         if (userId == UserHandle.USER_OWNER) {
4702             return resolveInfos;
4703         }
4704         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
4705             ResolveInfo info = resolveInfos.get(i);
4706             if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
4707                 resolveInfos.remove(i);
4708             }
4709         }
4710         return resolveInfos;
4711     }
4712
4713     private static boolean hasWebURI(Intent intent) {
4714         if (intent.getData() == null) {
4715             return false;
4716         }
4717         final String scheme = intent.getScheme();
4718         if (TextUtils.isEmpty(scheme)) {
4719             return false;
4720         }
4721         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
4722     }
4723
4724     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
4725             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
4726             int userId) {
4727         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
4728
4729         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
4730             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
4731                     candidates.size());
4732         }
4733
4734         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
4735         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
4736         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
4737         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
4738         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
4739         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
4740
4741         synchronized (mPackages) {
4742             final int count = candidates.size();
4743             // First, try to use linked apps. Partition the candidates into four lists:
4744             // one for the final results, one for the "do not use ever", one for "undefined status"
4745             // and finally one for "browser app type".
4746             for (int n=0; n<count; n++) {
4747                 ResolveInfo info = candidates.get(n);
4748                 String packageName = info.activityInfo.packageName;
4749                 PackageSetting ps = mSettings.mPackages.get(packageName);
4750                 if (ps != null) {
4751                     // Add to the special match all list (Browser use case)
4752                     if (info.handleAllWebDataURI) {
4753                         matchAllList.add(info);
4754                         continue;
4755                     }
4756                     // Try to get the status from User settings first
4757                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4758                     int status = (int)(packedStatus >> 32);
4759                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
4760                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
4761                         if (DEBUG_DOMAIN_VERIFICATION) {
4762                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
4763                                     + " : linkgen=" + linkGeneration);
4764                         }
4765                         // Use link-enabled generation as preferredOrder, i.e.
4766                         // prefer newly-enabled over earlier-enabled.
4767                         info.preferredOrder = linkGeneration;
4768                         alwaysList.add(info);
4769                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4770                         if (DEBUG_DOMAIN_VERIFICATION) {
4771                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
4772                         }
4773                         neverList.add(info);
4774                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4775                         if (DEBUG_DOMAIN_VERIFICATION) {
4776                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
4777                         }
4778                         alwaysAskList.add(info);
4779                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
4780                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
4781                         if (DEBUG_DOMAIN_VERIFICATION) {
4782                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
4783                         }
4784                         undefinedList.add(info);
4785                     }
4786                 }
4787             }
4788
4789             // We'll want to include browser possibilities in a few cases
4790             boolean includeBrowser = false;
4791
4792             // First try to add the "always" resolution(s) for the current user, if any
4793             if (alwaysList.size() > 0) {
4794                 result.addAll(alwaysList);
4795             } else {
4796                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
4797                 result.addAll(undefinedList);
4798                 // Maybe add one for the other profile.
4799                 if (xpDomainInfo != null && (
4800                         xpDomainInfo.bestDomainVerificationStatus
4801                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
4802                     result.add(xpDomainInfo.resolveInfo);
4803                 }
4804                 includeBrowser = true;
4805             }
4806
4807             // The presence of any 'always ask' alternatives means we'll also offer browsers.
4808             // If there were 'always' entries their preferred order has been set, so we also
4809             // back that off to make the alternatives equivalent
4810             if (alwaysAskList.size() > 0) {
4811                 for (ResolveInfo i : result) {
4812                     i.preferredOrder = 0;
4813                 }
4814                 result.addAll(alwaysAskList);
4815                 includeBrowser = true;
4816             }
4817
4818             if (includeBrowser) {
4819                 // Also add browsers (all of them or only the default one)
4820                 if (DEBUG_DOMAIN_VERIFICATION) {
4821                     Slog.v(TAG, "   ...including browsers in candidate set");
4822                 }
4823                 if ((matchFlags & MATCH_ALL) != 0) {
4824                     result.addAll(matchAllList);
4825                 } else {
4826                     // Browser/generic handling case.  If there's a default browser, go straight
4827                     // to that (but only if there is no other higher-priority match).
4828                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
4829                     int maxMatchPrio = 0;
4830                     ResolveInfo defaultBrowserMatch = null;
4831                     final int numCandidates = matchAllList.size();
4832                     for (int n = 0; n < numCandidates; n++) {
4833                         ResolveInfo info = matchAllList.get(n);
4834                         // track the highest overall match priority...
4835                         if (info.priority > maxMatchPrio) {
4836                             maxMatchPrio = info.priority;
4837                         }
4838                         // ...and the highest-priority default browser match
4839                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
4840                             if (defaultBrowserMatch == null
4841                                     || (defaultBrowserMatch.priority < info.priority)) {
4842                                 if (debug) {
4843                                     Slog.v(TAG, "Considering default browser match " + info);
4844                                 }
4845                                 defaultBrowserMatch = info;
4846                             }
4847                         }
4848                     }
4849                     if (defaultBrowserMatch != null
4850                             && defaultBrowserMatch.priority >= maxMatchPrio
4851                             && !TextUtils.isEmpty(defaultBrowserPackageName))
4852                     {
4853                         if (debug) {
4854                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
4855                         }
4856                         result.add(defaultBrowserMatch);
4857                     } else {
4858                         result.addAll(matchAllList);
4859                     }
4860                 }
4861
4862                 // If there is nothing selected, add all candidates and remove the ones that the user
4863                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
4864                 if (result.size() == 0) {
4865                     result.addAll(candidates);
4866                     result.removeAll(neverList);
4867                 }
4868             }
4869         }
4870         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
4871             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
4872                     result.size());
4873             for (ResolveInfo info : result) {
4874                 Slog.v(TAG, "  + " + info.activityInfo);
4875             }
4876         }
4877         return result;
4878     }
4879
4880     // Returns a packed value as a long:
4881     //
4882     // high 'int'-sized word: link status: undefined/ask/never/always.
4883     // low 'int'-sized word: relative priority among 'always' results.
4884     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
4885         long result = ps.getDomainVerificationStatusForUser(userId);
4886         // if none available, get the master status
4887         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
4888             if (ps.getIntentFilterVerificationInfo() != null) {
4889                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
4890             }
4891         }
4892         return result;
4893     }
4894
4895     private ResolveInfo querySkipCurrentProfileIntents(
4896             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4897             int flags, int sourceUserId) {
4898         if (matchingFilters != null) {
4899             int size = matchingFilters.size();
4900             for (int i = 0; i < size; i ++) {
4901                 CrossProfileIntentFilter filter = matchingFilters.get(i);
4902                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
4903                     // Checking if there are activities in the target user that can handle the
4904                     // intent.
4905                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4906                             flags, sourceUserId);
4907                     if (resolveInfo != null) {
4908                         return resolveInfo;
4909                     }
4910                 }
4911             }
4912         }
4913         return null;
4914     }
4915
4916     // Return matching ResolveInfo if any for skip current profile intent filters.
4917     private ResolveInfo queryCrossProfileIntents(
4918             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4919             int flags, int sourceUserId) {
4920         if (matchingFilters != null) {
4921             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
4922             // match the same intent. For performance reasons, it is better not to
4923             // run queryIntent twice for the same userId
4924             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
4925             int size = matchingFilters.size();
4926             for (int i = 0; i < size; i++) {
4927                 CrossProfileIntentFilter filter = matchingFilters.get(i);
4928                 int targetUserId = filter.getTargetUserId();
4929                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
4930                         && !alreadyTriedUserIds.get(targetUserId)) {
4931                     // Checking if there are activities in the target user that can handle the
4932                     // intent.
4933                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4934                             flags, sourceUserId);
4935                     if (resolveInfo != null) return resolveInfo;
4936                     alreadyTriedUserIds.put(targetUserId, true);
4937                 }
4938             }
4939         }
4940         return null;
4941     }
4942
4943     private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
4944             String resolvedType, int flags, int sourceUserId) {
4945         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4946                 resolvedType, flags, filter.getTargetUserId());
4947         if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
4948             return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
4949         }
4950         return null;
4951     }
4952
4953     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
4954             int sourceUserId, int targetUserId) {
4955         ResolveInfo forwardingResolveInfo = new ResolveInfo();
4956         String className;
4957         if (targetUserId == UserHandle.USER_OWNER) {
4958             className = FORWARD_INTENT_TO_USER_OWNER;
4959         } else {
4960             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
4961         }
4962         ComponentName forwardingActivityComponentName = new ComponentName(
4963                 mAndroidApplication.packageName, className);
4964         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
4965                 sourceUserId);
4966         if (targetUserId == UserHandle.USER_OWNER) {
4967             forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
4968             forwardingResolveInfo.noResourceId = true;
4969         }
4970         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
4971         forwardingResolveInfo.priority = 0;
4972         forwardingResolveInfo.preferredOrder = 0;
4973         forwardingResolveInfo.match = 0;
4974         forwardingResolveInfo.isDefault = true;
4975         forwardingResolveInfo.filter = filter;
4976         forwardingResolveInfo.targetUserId = targetUserId;
4977         return forwardingResolveInfo;
4978     }
4979
4980     @Override
4981     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
4982             Intent[] specifics, String[] specificTypes, Intent intent,
4983             String resolvedType, int flags, int userId) {
4984         if (!sUserManager.exists(userId)) return Collections.emptyList();
4985         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
4986                 false, "query intent activity options");
4987         final String resultsAction = intent.getAction();
4988
4989         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
4990                 | PackageManager.GET_RESOLVED_FILTER, userId);
4991
4992         if (DEBUG_INTENT_MATCHING) {
4993             Log.v(TAG, "Query " + intent + ": " + results);
4994         }
4995
4996         int specificsPos = 0;
4997         int N;
4998
4999         // todo: note that the algorithm used here is O(N^2).  This
5000         // isn't a problem in our current environment, but if we start running
5001         // into situations where we have more than 5 or 10 matches then this
5002         // should probably be changed to something smarter...
5003
5004         // First we go through and resolve each of the specific items
5005         // that were supplied, taking care of removing any corresponding
5006         // duplicate items in the generic resolve list.
5007         if (specifics != null) {
5008             for (int i=0; i<specifics.length; i++) {
5009                 final Intent sintent = specifics[i];
5010                 if (sintent == null) {
5011                     continue;
5012                 }
5013
5014                 if (DEBUG_INTENT_MATCHING) {
5015                     Log.v(TAG, "Specific #" + i + ": " + sintent);
5016                 }
5017
5018                 String action = sintent.getAction();
5019                 if (resultsAction != null && resultsAction.equals(action)) {
5020                     // If this action was explicitly requested, then don't
5021                     // remove things that have it.
5022                     action = null;
5023                 }
5024
5025                 ResolveInfo ri = null;
5026                 ActivityInfo ai = null;
5027
5028                 ComponentName comp = sintent.getComponent();
5029                 if (comp == null) {
5030                     ri = resolveIntent(
5031                         sintent,
5032                         specificTypes != null ? specificTypes[i] : null,
5033                             flags, userId);
5034                     if (ri == null) {
5035                         continue;
5036                     }
5037                     if (ri == mResolveInfo) {
5038                         // ACK!  Must do something better with this.
5039                     }
5040                     ai = ri.activityInfo;
5041                     comp = new ComponentName(ai.applicationInfo.packageName,
5042                             ai.name);
5043                 } else {
5044                     ai = getActivityInfo(comp, flags, userId);
5045                     if (ai == null) {
5046                         continue;
5047                     }
5048                 }
5049
5050                 // Look for any generic query activities that are duplicates
5051                 // of this specific one, and remove them from the results.
5052                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5053                 N = results.size();
5054                 int j;
5055                 for (j=specificsPos; j<N; j++) {
5056                     ResolveInfo sri = results.get(j);
5057                     if ((sri.activityInfo.name.equals(comp.getClassName())
5058                             && sri.activityInfo.applicationInfo.packageName.equals(
5059                                     comp.getPackageName()))
5060                         || (action != null && sri.filter.matchAction(action))) {
5061                         results.remove(j);
5062                         if (DEBUG_INTENT_MATCHING) Log.v(
5063                             TAG, "Removing duplicate item from " + j
5064                             + " due to specific " + specificsPos);
5065                         if (ri == null) {
5066                             ri = sri;
5067                         }
5068                         j--;
5069                         N--;
5070                     }
5071                 }
5072
5073                 // Add this specific item to its proper place.
5074                 if (ri == null) {
5075                     ri = new ResolveInfo();
5076                     ri.activityInfo = ai;
5077                 }
5078                 results.add(specificsPos, ri);
5079                 ri.specificIndex = i;
5080                 specificsPos++;
5081             }
5082         }
5083
5084         // Now we go through the remaining generic results and remove any
5085         // duplicate actions that are found here.
5086         N = results.size();
5087         for (int i=specificsPos; i<N-1; i++) {
5088             final ResolveInfo rii = results.get(i);
5089             if (rii.filter == null) {
5090                 continue;
5091             }
5092
5093             // Iterate over all of the actions of this result's intent
5094             // filter...  typically this should be just one.
5095             final Iterator<String> it = rii.filter.actionsIterator();
5096             if (it == null) {
5097                 continue;
5098             }
5099             while (it.hasNext()) {
5100                 final String action = it.next();
5101                 if (resultsAction != null && resultsAction.equals(action)) {
5102                     // If this action was explicitly requested, then don't
5103                     // remove things that have it.
5104                     continue;
5105                 }
5106                 for (int j=i+1; j<N; j++) {
5107                     final ResolveInfo rij = results.get(j);
5108                     if (rij.filter != null && rij.filter.hasAction(action)) {
5109                         results.remove(j);
5110                         if (DEBUG_INTENT_MATCHING) Log.v(
5111                             TAG, "Removing duplicate item from " + j
5112                             + " due to action " + action + " at " + i);
5113                         j--;
5114                         N--;
5115                     }
5116                 }
5117             }
5118
5119             // If the caller didn't request filter information, drop it now
5120             // so we don't have to marshall/unmarshall it.
5121             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5122                 rii.filter = null;
5123             }
5124         }
5125
5126         // Filter out the caller activity if so requested.
5127         if (caller != null) {
5128             N = results.size();
5129             for (int i=0; i<N; i++) {
5130                 ActivityInfo ainfo = results.get(i).activityInfo;
5131                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
5132                         && caller.getClassName().equals(ainfo.name)) {
5133                     results.remove(i);
5134                     break;
5135                 }
5136             }
5137         }
5138
5139         // If the caller didn't request filter information,
5140         // drop them now so we don't have to
5141         // marshall/unmarshall it.
5142         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5143             N = results.size();
5144             for (int i=0; i<N; i++) {
5145                 results.get(i).filter = null;
5146             }
5147         }
5148
5149         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
5150         return results;
5151     }
5152
5153     @Override
5154     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
5155             int userId) {
5156         if (!sUserManager.exists(userId)) return Collections.emptyList();
5157         ComponentName comp = intent.getComponent();
5158         if (comp == null) {
5159             if (intent.getSelector() != null) {
5160                 intent = intent.getSelector();
5161                 comp = intent.getComponent();
5162             }
5163         }
5164         if (comp != null) {
5165             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5166             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
5167             if (ai != null) {
5168                 ResolveInfo ri = new ResolveInfo();
5169                 ri.activityInfo = ai;
5170                 list.add(ri);
5171             }
5172             return list;
5173         }
5174
5175         // reader
5176         synchronized (mPackages) {
5177             String pkgName = intent.getPackage();
5178             if (pkgName == null) {
5179                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
5180             }
5181             final PackageParser.Package pkg = mPackages.get(pkgName);
5182             if (pkg != null) {
5183                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
5184                         userId);
5185             }
5186             return null;
5187         }
5188     }
5189
5190     @Override
5191     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
5192         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
5193         if (!sUserManager.exists(userId)) return null;
5194         if (query != null) {
5195             if (query.size() >= 1) {
5196                 // If there is more than one service with the same priority,
5197                 // just arbitrarily pick the first one.
5198                 return query.get(0);
5199             }
5200         }
5201         return null;
5202     }
5203
5204     @Override
5205     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
5206             int userId) {
5207         if (!sUserManager.exists(userId)) return Collections.emptyList();
5208         ComponentName comp = intent.getComponent();
5209         if (comp == null) {
5210             if (intent.getSelector() != null) {
5211                 intent = intent.getSelector();
5212                 comp = intent.getComponent();
5213             }
5214         }
5215         if (comp != null) {
5216             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5217             final ServiceInfo si = getServiceInfo(comp, flags, userId);
5218             if (si != null) {
5219                 final ResolveInfo ri = new ResolveInfo();
5220                 ri.serviceInfo = si;
5221                 list.add(ri);
5222             }
5223             return list;
5224         }
5225
5226         // reader
5227         synchronized (mPackages) {
5228             String pkgName = intent.getPackage();
5229             if (pkgName == null) {
5230                 return mServices.queryIntent(intent, resolvedType, flags, userId);
5231             }
5232             final PackageParser.Package pkg = mPackages.get(pkgName);
5233             if (pkg != null) {
5234                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
5235                         userId);
5236             }
5237             return null;
5238         }
5239     }
5240
5241     @Override
5242     public List<ResolveInfo> queryIntentContentProviders(
5243             Intent intent, String resolvedType, int flags, int userId) {
5244         if (!sUserManager.exists(userId)) return Collections.emptyList();
5245         ComponentName comp = intent.getComponent();
5246         if (comp == null) {
5247             if (intent.getSelector() != null) {
5248                 intent = intent.getSelector();
5249                 comp = intent.getComponent();
5250             }
5251         }
5252         if (comp != null) {
5253             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5254             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
5255             if (pi != null) {
5256                 final ResolveInfo ri = new ResolveInfo();
5257                 ri.providerInfo = pi;
5258                 list.add(ri);
5259             }
5260             return list;
5261         }
5262
5263         // reader
5264         synchronized (mPackages) {
5265             String pkgName = intent.getPackage();
5266             if (pkgName == null) {
5267                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
5268             }
5269             final PackageParser.Package pkg = mPackages.get(pkgName);
5270             if (pkg != null) {
5271                 return mProviders.queryIntentForPackage(
5272                         intent, resolvedType, flags, pkg.providers, userId);
5273             }
5274             return null;
5275         }
5276     }
5277
5278     @Override
5279     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5280         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5281
5282         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
5283
5284         // writer
5285         synchronized (mPackages) {
5286             ArrayList<PackageInfo> list;
5287             if (listUninstalled) {
5288                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
5289                 for (PackageSetting ps : mSettings.mPackages.values()) {
5290                     PackageInfo pi;
5291                     if (ps.pkg != null) {
5292                         pi = generatePackageInfo(ps.pkg, flags, userId);
5293                     } else {
5294                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5295                     }
5296                     if (pi != null) {
5297                         list.add(pi);
5298                     }
5299                 }
5300             } else {
5301                 list = new ArrayList<PackageInfo>(mPackages.size());
5302                 for (PackageParser.Package p : mPackages.values()) {
5303                     PackageInfo pi = generatePackageInfo(p, flags, userId);
5304                     if (pi != null) {
5305                         list.add(pi);
5306                     }
5307                 }
5308             }
5309
5310             return new ParceledListSlice<PackageInfo>(list);
5311         }
5312     }
5313
5314     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
5315             String[] permissions, boolean[] tmp, int flags, int userId) {
5316         int numMatch = 0;
5317         final PermissionsState permissionsState = ps.getPermissionsState();
5318         for (int i=0; i<permissions.length; i++) {
5319             final String permission = permissions[i];
5320             if (permissionsState.hasPermission(permission, userId)) {
5321                 tmp[i] = true;
5322                 numMatch++;
5323             } else {
5324                 tmp[i] = false;
5325             }
5326         }
5327         if (numMatch == 0) {
5328             return;
5329         }
5330         PackageInfo pi;
5331         if (ps.pkg != null) {
5332             pi = generatePackageInfo(ps.pkg, flags, userId);
5333         } else {
5334             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5335         }
5336         // The above might return null in cases of uninstalled apps or install-state
5337         // skew across users/profiles.
5338         if (pi != null) {
5339             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
5340                 if (numMatch == permissions.length) {
5341                     pi.requestedPermissions = permissions;
5342                 } else {
5343                     pi.requestedPermissions = new String[numMatch];
5344                     numMatch = 0;
5345                     for (int i=0; i<permissions.length; i++) {
5346                         if (tmp[i]) {
5347                             pi.requestedPermissions[numMatch] = permissions[i];
5348                             numMatch++;
5349                         }
5350                     }
5351                 }
5352             }
5353             list.add(pi);
5354         }
5355     }
5356
5357     @Override
5358     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
5359             String[] permissions, int flags, int userId) {
5360         if (!sUserManager.exists(userId)) return null;
5361         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5362
5363         // writer
5364         synchronized (mPackages) {
5365             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
5366             boolean[] tmpBools = new boolean[permissions.length];
5367             if (listUninstalled) {
5368                 for (PackageSetting ps : mSettings.mPackages.values()) {
5369                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
5370                 }
5371             } else {
5372                 for (PackageParser.Package pkg : mPackages.values()) {
5373                     PackageSetting ps = (PackageSetting)pkg.mExtras;
5374                     if (ps != null) {
5375                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
5376                                 userId);
5377                     }
5378                 }
5379             }
5380
5381             return new ParceledListSlice<PackageInfo>(list);
5382         }
5383     }
5384
5385     @Override
5386     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
5387         if (!sUserManager.exists(userId)) return null;
5388         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5389
5390         // writer
5391         synchronized (mPackages) {
5392             ArrayList<ApplicationInfo> list;
5393             if (listUninstalled) {
5394                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
5395                 for (PackageSetting ps : mSettings.mPackages.values()) {
5396                     ApplicationInfo ai;
5397                     if (ps.pkg != null) {
5398                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
5399                                 ps.readUserState(userId), userId);
5400                     } else {
5401                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
5402                     }
5403                     if (ai != null) {
5404                         list.add(ai);
5405                     }
5406                 }
5407             } else {
5408                 list = new ArrayList<ApplicationInfo>(mPackages.size());
5409                 for (PackageParser.Package p : mPackages.values()) {
5410                     if (p.mExtras != null) {
5411                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5412                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
5413                         if (ai != null) {
5414                             list.add(ai);
5415                         }
5416                     }
5417                 }
5418             }
5419
5420             return new ParceledListSlice<ApplicationInfo>(list);
5421         }
5422     }
5423
5424     public List<ApplicationInfo> getPersistentApplications(int flags) {
5425         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
5426
5427         // reader
5428         synchronized (mPackages) {
5429             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
5430             final int userId = UserHandle.getCallingUserId();
5431             while (i.hasNext()) {
5432                 final PackageParser.Package p = i.next();
5433                 if (p.applicationInfo != null
5434                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
5435                         && (!mSafeMode || isSystemApp(p))) {
5436                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
5437                     if (ps != null) {
5438                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5439                                 ps.readUserState(userId), userId);
5440                         if (ai != null) {
5441                             finalList.add(ai);
5442                         }
5443                     }
5444                 }
5445             }
5446         }
5447
5448         return finalList;
5449     }
5450
5451     @Override
5452     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
5453         if (!sUserManager.exists(userId)) return null;
5454         // reader
5455         synchronized (mPackages) {
5456             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
5457             PackageSetting ps = provider != null
5458                     ? mSettings.mPackages.get(provider.owner.packageName)
5459                     : null;
5460             return ps != null
5461                     && mSettings.isEnabledLPr(provider.info, flags, userId)
5462                     && (!mSafeMode || (provider.info.applicationInfo.flags
5463                             &ApplicationInfo.FLAG_SYSTEM) != 0)
5464                     ? PackageParser.generateProviderInfo(provider, flags,
5465                             ps.readUserState(userId), userId)
5466                     : null;
5467         }
5468     }
5469
5470     /**
5471      * @deprecated
5472      */
5473     @Deprecated
5474     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
5475         // reader
5476         synchronized (mPackages) {
5477             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
5478                     .entrySet().iterator();
5479             final int userId = UserHandle.getCallingUserId();
5480             while (i.hasNext()) {
5481                 Map.Entry<String, PackageParser.Provider> entry = i.next();
5482                 PackageParser.Provider p = entry.getValue();
5483                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5484
5485                 if (ps != null && p.syncable
5486                         && (!mSafeMode || (p.info.applicationInfo.flags
5487                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
5488                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
5489                             ps.readUserState(userId), userId);
5490                     if (info != null) {
5491                         outNames.add(entry.getKey());
5492                         outInfo.add(info);
5493                     }
5494                 }
5495             }
5496         }
5497     }
5498
5499     @Override
5500     public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
5501             int uid, int flags) {
5502         ArrayList<ProviderInfo> finalList = null;
5503         // reader
5504         synchronized (mPackages) {
5505             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
5506             final int userId = processName != null ?
5507                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
5508             while (i.hasNext()) {
5509                 final PackageParser.Provider p = i.next();
5510                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5511                 if (ps != null && p.info.authority != null
5512                         && (processName == null
5513                                 || (p.info.processName.equals(processName)
5514                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
5515                         && mSettings.isEnabledLPr(p.info, flags, userId)
5516                         && (!mSafeMode
5517                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
5518                     if (finalList == null) {
5519                         finalList = new ArrayList<ProviderInfo>(3);
5520                     }
5521                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
5522                             ps.readUserState(userId), userId);
5523                     if (info != null) {
5524                         finalList.add(info);
5525                     }
5526                 }
5527             }
5528         }
5529
5530         if (finalList != null) {
5531             Collections.sort(finalList, mProviderInitOrderSorter);
5532             return new ParceledListSlice<ProviderInfo>(finalList);
5533         }
5534
5535         return null;
5536     }
5537
5538     @Override
5539     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
5540             int flags) {
5541         // reader
5542         synchronized (mPackages) {
5543             final PackageParser.Instrumentation i = mInstrumentation.get(name);
5544             return PackageParser.generateInstrumentationInfo(i, flags);
5545         }
5546     }
5547
5548     @Override
5549     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
5550             int flags) {
5551         ArrayList<InstrumentationInfo> finalList =
5552             new ArrayList<InstrumentationInfo>();
5553
5554         // reader
5555         synchronized (mPackages) {
5556             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
5557             while (i.hasNext()) {
5558                 final PackageParser.Instrumentation p = i.next();
5559                 if (targetPackage == null
5560                         || targetPackage.equals(p.info.targetPackage)) {
5561                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
5562                             flags);
5563                     if (ii != null) {
5564                         finalList.add(ii);
5565                     }
5566                 }
5567             }
5568         }
5569
5570         return finalList;
5571     }
5572
5573     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
5574         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
5575         if (overlays == null) {
5576             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
5577             return;
5578         }
5579         for (PackageParser.Package opkg : overlays.values()) {
5580             // Not much to do if idmap fails: we already logged the error
5581             // and we certainly don't want to abort installation of pkg simply
5582             // because an overlay didn't fit properly. For these reasons,
5583             // ignore the return value of createIdmapForPackagePairLI.
5584             createIdmapForPackagePairLI(pkg, opkg);
5585         }
5586     }
5587
5588     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
5589             PackageParser.Package opkg) {
5590         if (!opkg.mTrustedOverlay) {
5591             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
5592                     opkg.baseCodePath + ": overlay not trusted");
5593             return false;
5594         }
5595         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
5596         if (overlaySet == null) {
5597             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
5598                     opkg.baseCodePath + " but target package has no known overlays");
5599             return false;
5600         }
5601         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
5602         // TODO: generate idmap for split APKs
5603         if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
5604             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
5605                     + opkg.baseCodePath);
5606             return false;
5607         }
5608         PackageParser.Package[] overlayArray =
5609             overlaySet.values().toArray(new PackageParser.Package[0]);
5610         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
5611             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
5612                 return p1.mOverlayPriority - p2.mOverlayPriority;
5613             }
5614         };
5615         Arrays.sort(overlayArray, cmp);
5616
5617         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
5618         int i = 0;
5619         for (PackageParser.Package p : overlayArray) {
5620             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
5621         }
5622         return true;
5623     }
5624
5625     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
5626         final File[] files = dir.listFiles();
5627         if (ArrayUtils.isEmpty(files)) {
5628             Log.d(TAG, "No files in app dir " + dir);
5629             return;
5630         }
5631
5632         if (DEBUG_PACKAGE_SCANNING) {
5633             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
5634                     + " flags=0x" + Integer.toHexString(parseFlags));
5635         }
5636
5637         for (File file : files) {
5638             final boolean isPackage = (isApkFile(file) || file.isDirectory())
5639                     && !PackageInstallerService.isStageName(file.getName());
5640             if (!isPackage) {
5641                 // Ignore entries which are not packages
5642                 continue;
5643             }
5644             try {
5645                 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
5646                         scanFlags, currentTime, null);
5647             } catch (PackageManagerException e) {
5648                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
5649
5650                 // Delete invalid userdata apps
5651                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
5652                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
5653                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
5654                     if (file.isDirectory()) {
5655                         mInstaller.rmPackageDir(file.getAbsolutePath());
5656                     } else {
5657                         file.delete();
5658                     }
5659                 }
5660             }
5661         }
5662     }
5663
5664     private static File getSettingsProblemFile() {
5665         File dataDir = Environment.getDataDirectory();
5666         File systemDir = new File(dataDir, "system");
5667         File fname = new File(systemDir, "uiderrors.txt");
5668         return fname;
5669     }
5670
5671     static void reportSettingsProblem(int priority, String msg) {
5672         logCriticalInfo(priority, msg);
5673     }
5674
5675     static void logCriticalInfo(int priority, String msg) {
5676         Slog.println(priority, TAG, msg);
5677         EventLogTags.writePmCriticalInfo(msg);
5678         try {
5679             File fname = getSettingsProblemFile();
5680             FileOutputStream out = new FileOutputStream(fname, true);
5681             PrintWriter pw = new FastPrintWriter(out);
5682             SimpleDateFormat formatter = new SimpleDateFormat();
5683             String dateString = formatter.format(new Date(System.currentTimeMillis()));
5684             pw.println(dateString + ": " + msg);
5685             pw.close();
5686             FileUtils.setPermissions(
5687                     fname.toString(),
5688                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
5689                     -1, -1);
5690         } catch (java.io.IOException e) {
5691         }
5692     }
5693
5694     private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
5695             PackageParser.Package pkg, File srcFile, int parseFlags)
5696             throws PackageManagerException {
5697         if (ps != null
5698                 && ps.codePath.equals(srcFile)
5699                 && ps.timeStamp == srcFile.lastModified()
5700                 && !isCompatSignatureUpdateNeeded(pkg)
5701                 && !isRecoverSignatureUpdateNeeded(pkg)) {
5702             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
5703             KeySetManagerService ksms = mSettings.mKeySetManagerService;
5704             ArraySet<PublicKey> signingKs;
5705             synchronized (mPackages) {
5706                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
5707             }
5708             if (ps.signatures.mSignatures != null
5709                     && ps.signatures.mSignatures.length != 0
5710                     && signingKs != null) {
5711                 // Optimization: reuse the existing cached certificates
5712                 // if the package appears to be unchanged.
5713                 pkg.mSignatures = ps.signatures.mSignatures;
5714                 pkg.mSigningKeys = signingKs;
5715                 return;
5716             }
5717
5718             Slog.w(TAG, "PackageSetting for " + ps.name
5719                     + " is missing signatures.  Collecting certs again to recover them.");
5720         } else {
5721             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
5722         }
5723
5724         try {
5725             pp.collectCertificates(pkg, parseFlags);
5726             pp.collectManifestDigest(pkg);
5727         } catch (PackageParserException e) {
5728             throw PackageManagerException.from(e);
5729         }
5730     }
5731
5732     /*
5733      *  Scan a package and return the newly parsed package.
5734      *  Returns null in case of errors and the error code is stored in mLastScanError
5735      */
5736     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
5737             long currentTime, UserHandle user) throws PackageManagerException {
5738         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
5739         parseFlags |= mDefParseFlags;
5740         PackageParser pp = new PackageParser();
5741         pp.setSeparateProcesses(mSeparateProcesses);
5742         pp.setOnlyCoreApps(mOnlyCore);
5743         pp.setDisplayMetrics(mMetrics);
5744
5745         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
5746             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
5747         }
5748
5749         final PackageParser.Package pkg;
5750         try {
5751             pkg = pp.parsePackage(scanFile, parseFlags);
5752         } catch (PackageParserException e) {
5753             throw PackageManagerException.from(e);
5754         }
5755
5756         PackageSetting ps = null;
5757         PackageSetting updatedPkg;
5758         // reader
5759         synchronized (mPackages) {
5760             // Look to see if we already know about this package.
5761             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
5762             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
5763                 // This package has been renamed to its original name.  Let's
5764                 // use that.
5765                 ps = mSettings.peekPackageLPr(oldName);
5766             }
5767             // If there was no original package, see one for the real package name.
5768             if (ps == null) {
5769                 ps = mSettings.peekPackageLPr(pkg.packageName);
5770             }
5771             // Check to see if this package could be hiding/updating a system
5772             // package.  Must look for it either under the original or real
5773             // package name depending on our state.
5774             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
5775             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
5776         }
5777         boolean updatedPkgBetter = false;
5778         // First check if this is a system package that may involve an update
5779         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5780             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
5781             // it needs to drop FLAG_PRIVILEGED.
5782             if (locationIsPrivileged(scanFile)) {
5783                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
5784             } else {
5785                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
5786             }
5787
5788             if (ps != null && !ps.codePath.equals(scanFile)) {
5789                 // The path has changed from what was last scanned...  check the
5790                 // version of the new path against what we have stored to determine
5791                 // what to do.
5792                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
5793                 if (pkg.mVersionCode <= ps.versionCode) {
5794                     // The system package has been updated and the code path does not match
5795                     // Ignore entry. Skip it.
5796                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
5797                             + " ignored: updated version " + ps.versionCode
5798                             + " better than this " + pkg.mVersionCode);
5799                     if (!updatedPkg.codePath.equals(scanFile)) {
5800                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
5801                                 + ps.name + " changing from " + updatedPkg.codePathString
5802                                 + " to " + scanFile);
5803                         updatedPkg.codePath = scanFile;
5804                         updatedPkg.codePathString = scanFile.toString();
5805                         updatedPkg.resourcePath = scanFile;
5806                         updatedPkg.resourcePathString = scanFile.toString();
5807                     }
5808                     updatedPkg.pkg = pkg;
5809                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5810                             "Package " + ps.name + " at " + scanFile
5811                                     + " ignored: updated version " + ps.versionCode
5812                                     + " better than this " + pkg.mVersionCode);
5813                 } else {
5814                     // The current app on the system partition is better than
5815                     // what we have updated to on the data partition; switch
5816                     // back to the system partition version.
5817                     // At this point, its safely assumed that package installation for
5818                     // apps in system partition will go through. If not there won't be a working
5819                     // version of the app
5820                     // writer
5821                     synchronized (mPackages) {
5822                         // Just remove the loaded entries from package lists.
5823                         mPackages.remove(ps.name);
5824                     }
5825
5826                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5827                             + " reverting from " + ps.codePathString
5828                             + ": new version " + pkg.mVersionCode
5829                             + " better than installed " + ps.versionCode);
5830
5831                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5832                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5833                     synchronized (mInstallLock) {
5834                         args.cleanUpResourcesLI();
5835                     }
5836                     synchronized (mPackages) {
5837                         mSettings.enableSystemPackageLPw(ps.name);
5838                     }
5839                     updatedPkgBetter = true;
5840                 }
5841             }
5842         }
5843
5844         if (updatedPkg != null) {
5845             // An updated system app will not have the PARSE_IS_SYSTEM flag set
5846             // initially
5847             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
5848
5849             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
5850             // flag set initially
5851             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
5852                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
5853             }
5854         }
5855
5856         // Verify certificates against what was last scanned
5857         collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
5858
5859         /*
5860          * A new system app appeared, but we already had a non-system one of the
5861          * same name installed earlier.
5862          */
5863         boolean shouldHideSystemApp = false;
5864         if (updatedPkg == null && ps != null
5865                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
5866             /*
5867              * Check to make sure the signatures match first. If they don't,
5868              * wipe the installed application and its data.
5869              */
5870             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
5871                     != PackageManager.SIGNATURE_MATCH) {
5872                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
5873                         + " signatures don't match existing userdata copy; removing");
5874                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
5875                 ps = null;
5876             } else {
5877                 /*
5878                  * If the newly-added system app is an older version than the
5879                  * already installed version, hide it. It will be scanned later
5880                  * and re-added like an update.
5881                  */
5882                 if (pkg.mVersionCode <= ps.versionCode) {
5883                     shouldHideSystemApp = true;
5884                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
5885                             + " but new version " + pkg.mVersionCode + " better than installed "
5886                             + ps.versionCode + "; hiding system");
5887                 } else {
5888                     /*
5889                      * The newly found system app is a newer version that the
5890                      * one previously installed. Simply remove the
5891                      * already-installed application and replace it with our own
5892                      * while keeping the application data.
5893                      */
5894                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5895                             + " reverting from " + ps.codePathString + ": new version "
5896                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
5897                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5898                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5899                     synchronized (mInstallLock) {
5900                         args.cleanUpResourcesLI();
5901                     }
5902                 }
5903             }
5904         }
5905
5906         // The apk is forward locked (not public) if its code and resources
5907         // are kept in different files. (except for app in either system or
5908         // vendor path).
5909         // TODO grab this value from PackageSettings
5910         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5911             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
5912                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
5913             }
5914         }
5915
5916         // TODO: extend to support forward-locked splits
5917         String resourcePath = null;
5918         String baseResourcePath = null;
5919         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
5920             if (ps != null && ps.resourcePathString != null) {
5921                 resourcePath = ps.resourcePathString;
5922                 baseResourcePath = ps.resourcePathString;
5923             } else {
5924                 // Should not happen at all. Just log an error.
5925                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
5926             }
5927         } else {
5928             resourcePath = pkg.codePath;
5929             baseResourcePath = pkg.baseCodePath;
5930         }
5931
5932         // Set application objects path explicitly.
5933         pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
5934         pkg.applicationInfo.setCodePath(pkg.codePath);
5935         pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
5936         pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
5937         pkg.applicationInfo.setResourcePath(resourcePath);
5938         pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
5939         pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
5940
5941         // Note that we invoke the following method only if we are about to unpack an application
5942         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
5943                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
5944
5945         /*
5946          * If the system app should be overridden by a previously installed
5947          * data, hide the system app now and let the /data/app scan pick it up
5948          * again.
5949          */
5950         if (shouldHideSystemApp) {
5951             synchronized (mPackages) {
5952                 mSettings.disableSystemPackageLPw(pkg.packageName);
5953             }
5954         }
5955
5956         return scannedPkg;
5957     }
5958
5959     private static String fixProcessName(String defProcessName,
5960             String processName, int uid) {
5961         if (processName == null) {
5962             return defProcessName;
5963         }
5964         return processName;
5965     }
5966
5967     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
5968             throws PackageManagerException {
5969         if (pkgSetting.signatures.mSignatures != null) {
5970             // Already existing package. Make sure signatures match
5971             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
5972                     == PackageManager.SIGNATURE_MATCH;
5973             if (!match) {
5974                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
5975                         == PackageManager.SIGNATURE_MATCH;
5976             }
5977             if (!match) {
5978                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
5979                         == PackageManager.SIGNATURE_MATCH;
5980             }
5981             if (!match) {
5982                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5983                         + pkg.packageName + " signatures do not match the "
5984                         + "previously installed version; ignoring!");
5985             }
5986         }
5987
5988         // Check for shared user signatures
5989         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
5990             // Already existing package. Make sure signatures match
5991             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5992                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
5993             if (!match) {
5994                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
5995                         == PackageManager.SIGNATURE_MATCH;
5996             }
5997             if (!match) {
5998                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
5999                         == PackageManager.SIGNATURE_MATCH;
6000             }
6001             if (!match) {
6002                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
6003                         "Package " + pkg.packageName
6004                         + " has no signatures that match those in shared user "
6005                         + pkgSetting.sharedUser.name + "; ignoring!");
6006             }
6007         }
6008     }
6009
6010     /**
6011      * Enforces that only the system UID or root's UID can call a method exposed
6012      * via Binder.
6013      *
6014      * @param message used as message if SecurityException is thrown
6015      * @throws SecurityException if the caller is not system or root
6016      */
6017     private static final void enforceSystemOrRoot(String message) {
6018         final int uid = Binder.getCallingUid();
6019         if (uid != Process.SYSTEM_UID && uid != 0) {
6020             throw new SecurityException(message);
6021         }
6022     }
6023
6024     @Override
6025     public void performBootDexOpt() {
6026         enforceSystemOrRoot("Only the system can request dexopt be performed");
6027
6028         // Before everything else, see whether we need to fstrim.
6029         try {
6030             IMountService ms = PackageHelper.getMountService();
6031             if (ms != null) {
6032                 final boolean isUpgrade = isUpgrade();
6033                 boolean doTrim = isUpgrade;
6034                 if (doTrim) {
6035                     Slog.w(TAG, "Running disk maintenance immediately due to system update");
6036                 } else {
6037                     final long interval = android.provider.Settings.Global.getLong(
6038                             mContext.getContentResolver(),
6039                             android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
6040                             DEFAULT_MANDATORY_FSTRIM_INTERVAL);
6041                     if (interval > 0) {
6042                         final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
6043                         if (timeSinceLast > interval) {
6044                             doTrim = true;
6045                             Slog.w(TAG, "No disk maintenance in " + timeSinceLast
6046                                     + "; running immediately");
6047                         }
6048                     }
6049                 }
6050                 if (doTrim) {
6051                     if (!isFirstBoot()) {
6052                         try {
6053                             ActivityManagerNative.getDefault().showBootMessage(
6054                                     mContext.getResources().getString(
6055                                             R.string.android_upgrading_fstrim), true);
6056                         } catch (RemoteException e) {
6057                         }
6058                     }
6059                     ms.runMaintenance();
6060                 }
6061             } else {
6062                 Slog.e(TAG, "Mount service unavailable!");
6063             }
6064         } catch (RemoteException e) {
6065             // Can't happen; MountService is local
6066         }
6067
6068         final ArraySet<PackageParser.Package> pkgs;
6069         synchronized (mPackages) {
6070             pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages();
6071         }
6072
6073         if (pkgs != null) {
6074             // Sort apps by importance for dexopt ordering. Important apps are given more priority
6075             // in case the device runs out of space.
6076             ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
6077             // Give priority to core apps.
6078             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
6079                 PackageParser.Package pkg = it.next();
6080                 if (pkg.coreApp) {
6081                     if (DEBUG_DEXOPT) {
6082                         Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
6083                     }
6084                     sortedPkgs.add(pkg);
6085                     it.remove();
6086                 }
6087             }
6088             // Give priority to system apps that listen for pre boot complete.
6089             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6090             ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
6091             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
6092                 PackageParser.Package pkg = it.next();
6093                 if (pkgNames.contains(pkg.packageName)) {
6094                     if (DEBUG_DEXOPT) {
6095                         Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
6096                     }
6097                     sortedPkgs.add(pkg);
6098                     it.remove();
6099                 }
6100             }
6101             // Filter out packages that aren't recently used.
6102             filterRecentlyUsedApps(pkgs);
6103             // Add all remaining apps.
6104             for (PackageParser.Package pkg : pkgs) {
6105                 if (DEBUG_DEXOPT) {
6106                     Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
6107                 }
6108                 sortedPkgs.add(pkg);
6109             }
6110
6111             // If we want to be lazy, filter everything that wasn't recently used.
6112             if (mLazyDexOpt) {
6113                 filterRecentlyUsedApps(sortedPkgs);
6114             }
6115
6116             int i = 0;
6117             int total = sortedPkgs.size();
6118             File dataDir = Environment.getDataDirectory();
6119             long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
6120             if (lowThreshold == 0) {
6121                 throw new IllegalStateException("Invalid low memory threshold");
6122             }
6123             for (PackageParser.Package pkg : sortedPkgs) {
6124                 long usableSpace = dataDir.getUsableSpace();
6125                 if (usableSpace < lowThreshold) {
6126                     Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
6127                     break;
6128                 }
6129                 performBootDexOpt(pkg, ++i, total);
6130             }
6131         }
6132     }
6133
6134     private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
6135         // Filter out packages that aren't recently used.
6136         //
6137         // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
6138         // should do a full dexopt.
6139         if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
6140             int total = pkgs.size();
6141             int skipped = 0;
6142             long now = System.currentTimeMillis();
6143             for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
6144                 PackageParser.Package pkg = i.next();
6145                 long then = pkg.mLastPackageUsageTimeInMills;
6146                 if (then + mDexOptLRUThresholdInMills < now) {
6147                     if (DEBUG_DEXOPT) {
6148                         Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
6149                               ((then == 0) ? "never" : new Date(then)));
6150                     }
6151                     i.remove();
6152                     skipped++;
6153                 }
6154             }
6155             if (DEBUG_DEXOPT) {
6156                 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
6157             }
6158         }
6159     }
6160
6161     private ArraySet<String> getPackageNamesForIntent(Intent intent) {
6162         List<ResolveInfo> ris = null;
6163         try {
6164             ris = AppGlobals.getPackageManager().queryIntentReceivers(
6165                     intent, null, 0, UserHandle.USER_OWNER);
6166         } catch (RemoteException e) {
6167         }
6168         ArraySet<String> pkgNames = new ArraySet<String>();
6169         if (ris != null) {
6170             for (ResolveInfo ri : ris) {
6171                 pkgNames.add(ri.activityInfo.packageName);
6172             }
6173         }
6174         return pkgNames;
6175     }
6176
6177     private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
6178         if (DEBUG_DEXOPT) {
6179             Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
6180         }
6181         if (!isFirstBoot()) {
6182             try {
6183                 ActivityManagerNative.getDefault().showBootMessage(
6184                         mContext.getResources().getString(R.string.android_upgrading_apk,
6185                                 curr, total), true);
6186             } catch (RemoteException e) {
6187             }
6188         }
6189         PackageParser.Package p = pkg;
6190         synchronized (mInstallLock) {
6191             mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */,
6192                     false /* force dex */, false /* defer */, true /* include dependencies */,
6193                     false /* boot complete */);
6194         }
6195     }
6196
6197     @Override
6198     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
6199         return performDexOpt(packageName, instructionSet, false);
6200     }
6201
6202     public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
6203         boolean dexopt = mLazyDexOpt || backgroundDexopt;
6204         boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
6205         if (!dexopt && !updateUsage) {
6206             // We aren't going to dexopt or update usage, so bail early.
6207             return false;
6208         }
6209         PackageParser.Package p;
6210         final String targetInstructionSet;
6211         synchronized (mPackages) {
6212             p = mPackages.get(packageName);
6213             if (p == null) {
6214                 return false;
6215             }
6216             if (updateUsage) {
6217                 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
6218             }
6219             mPackageUsage.write(false);
6220             if (!dexopt) {
6221                 // We aren't going to dexopt, so bail early.
6222                 return false;
6223             }
6224
6225             targetInstructionSet = instructionSet != null ? instructionSet :
6226                     getPrimaryInstructionSet(p.applicationInfo);
6227             if (p.mDexOptPerformed.contains(targetInstructionSet)) {
6228                 return false;
6229             }
6230         }
6231         long callingId = Binder.clearCallingIdentity();
6232         try {
6233             synchronized (mInstallLock) {
6234                 final String[] instructionSets = new String[] { targetInstructionSet };
6235                 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
6236                         false /* forceDex */, false /* defer */, true /* inclDependencies */,
6237                         true /* boot complete */);
6238                 return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
6239             }
6240         } finally {
6241             Binder.restoreCallingIdentity(callingId);
6242         }
6243     }
6244
6245     public ArraySet<String> getPackagesThatNeedDexOpt() {
6246         ArraySet<String> pkgs = null;
6247         synchronized (mPackages) {
6248             for (PackageParser.Package p : mPackages.values()) {
6249                 if (DEBUG_DEXOPT) {
6250                     Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
6251                 }
6252                 if (!p.mDexOptPerformed.isEmpty()) {
6253                     continue;
6254                 }
6255                 if (pkgs == null) {
6256                     pkgs = new ArraySet<String>();
6257                 }
6258                 pkgs.add(p.packageName);
6259             }
6260         }
6261         return pkgs;
6262     }
6263
6264     public void shutdown() {
6265         mPackageUsage.write(true);
6266     }
6267
6268     @Override
6269     public void forceDexOpt(String packageName) {
6270         enforceSystemOrRoot("forceDexOpt");
6271
6272         PackageParser.Package pkg;
6273         synchronized (mPackages) {
6274             pkg = mPackages.get(packageName);
6275             if (pkg == null) {
6276                 throw new IllegalArgumentException("Missing package: " + packageName);
6277             }
6278         }
6279
6280         synchronized (mInstallLock) {
6281             final String[] instructionSets = new String[] {
6282                     getPrimaryInstructionSet(pkg.applicationInfo) };
6283             final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
6284                     true /*forceDex*/, false /* defer */, true /* inclDependencies */,
6285                     true /* boot complete */);
6286             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
6287                 throw new IllegalStateException("Failed to dexopt: " + res);
6288             }
6289         }
6290     }
6291
6292     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
6293         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6294             Slog.w(TAG, "Unable to update from " + oldPkg.name
6295                     + " to " + newPkg.packageName
6296                     + ": old package not in system partition");
6297             return false;
6298         } else if (mPackages.get(oldPkg.name) != null) {
6299             Slog.w(TAG, "Unable to update from " + oldPkg.name
6300                     + " to " + newPkg.packageName
6301                     + ": old package still exists");
6302             return false;
6303         }
6304         return true;
6305     }
6306
6307     private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) {
6308         int[] users = sUserManager.getUserIds();
6309         int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo);
6310         if (res < 0) {
6311             return res;
6312         }
6313         for (int user : users) {
6314             if (user != 0) {
6315                 res = mInstaller.createUserData(volumeUuid, packageName,
6316                         UserHandle.getUid(user, uid), user, seinfo);
6317                 if (res < 0) {
6318                     return res;
6319                 }
6320             }
6321         }
6322         return res;
6323     }
6324
6325     private int removeDataDirsLI(String volumeUuid, String packageName) {
6326         int[] users = sUserManager.getUserIds();
6327         int res = 0;
6328         for (int user : users) {
6329             int resInner = mInstaller.remove(volumeUuid, packageName, user);
6330             if (resInner < 0) {
6331                 res = resInner;
6332             }
6333         }
6334
6335         return res;
6336     }
6337
6338     private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
6339         int[] users = sUserManager.getUserIds();
6340         int res = 0;
6341         for (int user : users) {
6342             int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user);
6343             if (resInner < 0) {
6344                 res = resInner;
6345             }
6346         }
6347         return res;
6348     }
6349
6350     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
6351             PackageParser.Package changingLib) {
6352         if (file.path != null) {
6353             usesLibraryFiles.add(file.path);
6354             return;
6355         }
6356         PackageParser.Package p = mPackages.get(file.apk);
6357         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
6358             // If we are doing this while in the middle of updating a library apk,
6359             // then we need to make sure to use that new apk for determining the
6360             // dependencies here.  (We haven't yet finished committing the new apk
6361             // to the package manager state.)
6362             if (p == null || p.packageName.equals(changingLib.packageName)) {
6363                 p = changingLib;
6364             }
6365         }
6366         if (p != null) {
6367             usesLibraryFiles.addAll(p.getAllCodePaths());
6368         }
6369     }
6370
6371     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
6372             PackageParser.Package changingLib) throws PackageManagerException {
6373         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
6374             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
6375             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
6376             for (int i=0; i<N; i++) {
6377                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
6378                 if (file == null) {
6379                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
6380                             "Package " + pkg.packageName + " requires unavailable shared library "
6381                             + pkg.usesLibraries.get(i) + "; failing!");
6382                 }
6383                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6384             }
6385             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
6386             for (int i=0; i<N; i++) {
6387                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
6388                 if (file == null) {
6389                     Slog.w(TAG, "Package " + pkg.packageName
6390                             + " desires unavailable shared library "
6391                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
6392                 } else {
6393                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6394                 }
6395             }
6396             N = usesLibraryFiles.size();
6397             if (N > 0) {
6398                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
6399             } else {
6400                 pkg.usesLibraryFiles = null;
6401             }
6402         }
6403     }
6404
6405     private static boolean hasString(List<String> list, List<String> which) {
6406         if (list == null) {
6407             return false;
6408         }
6409         for (int i=list.size()-1; i>=0; i--) {
6410             for (int j=which.size()-1; j>=0; j--) {
6411                 if (which.get(j).equals(list.get(i))) {
6412                     return true;
6413                 }
6414             }
6415         }
6416         return false;
6417     }
6418
6419     private void updateAllSharedLibrariesLPw() {
6420         for (PackageParser.Package pkg : mPackages.values()) {
6421             try {
6422                 updateSharedLibrariesLPw(pkg, null);
6423             } catch (PackageManagerException e) {
6424                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6425             }
6426         }
6427     }
6428
6429     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
6430             PackageParser.Package changingPkg) {
6431         ArrayList<PackageParser.Package> res = null;
6432         for (PackageParser.Package pkg : mPackages.values()) {
6433             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
6434                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
6435                 if (res == null) {
6436                     res = new ArrayList<PackageParser.Package>();
6437                 }
6438                 res.add(pkg);
6439                 try {
6440                     updateSharedLibrariesLPw(pkg, changingPkg);
6441                 } catch (PackageManagerException e) {
6442                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6443                 }
6444             }
6445         }
6446         return res;
6447     }
6448
6449     /**
6450      * Derive the value of the {@code cpuAbiOverride} based on the provided
6451      * value and an optional stored value from the package settings.
6452      */
6453     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
6454         String cpuAbiOverride = null;
6455
6456         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
6457             cpuAbiOverride = null;
6458         } else if (abiOverride != null) {
6459             cpuAbiOverride = abiOverride;
6460         } else if (settings != null) {
6461             cpuAbiOverride = settings.cpuAbiOverrideString;
6462         }
6463
6464         return cpuAbiOverride;
6465     }
6466
6467     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
6468             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6469         boolean success = false;
6470         try {
6471             final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
6472                     currentTime, user);
6473             success = true;
6474             return res;
6475         } finally {
6476             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
6477                 removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
6478             }
6479         }
6480     }
6481
6482     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
6483             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6484         final File scanFile = new File(pkg.codePath);
6485         if (pkg.applicationInfo.getCodePath() == null ||
6486                 pkg.applicationInfo.getResourcePath() == null) {
6487             // Bail out. The resource and code paths haven't been set.
6488             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
6489                     "Code and resource paths haven't been set correctly");
6490         }
6491
6492         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
6493             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
6494         } else {
6495             // Only allow system apps to be flagged as core apps.
6496             pkg.coreApp = false;
6497         }
6498
6499         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
6500             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6501         }
6502
6503         if (mCustomResolverComponentName != null &&
6504                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
6505             setUpCustomResolverActivity(pkg);
6506         }
6507
6508         if (pkg.packageName.equals("android")) {
6509             synchronized (mPackages) {
6510                 if (mAndroidApplication != null) {
6511                     Slog.w(TAG, "*************************************************");
6512                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
6513                     Slog.w(TAG, " file=" + scanFile);
6514                     Slog.w(TAG, "*************************************************");
6515                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6516                             "Core android package being redefined.  Skipping.");
6517                 }
6518
6519                 // Set up information for our fall-back user intent resolution activity.
6520                 mPlatformPackage = pkg;
6521                 pkg.mVersionCode = mSdkVersion;
6522                 mAndroidApplication = pkg.applicationInfo;
6523
6524                 if (!mResolverReplaced) {
6525                     mResolveActivity.applicationInfo = mAndroidApplication;
6526                     mResolveActivity.name = ResolverActivity.class.getName();
6527                     mResolveActivity.packageName = mAndroidApplication.packageName;
6528                     mResolveActivity.processName = "system:ui";
6529                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6530                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
6531                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
6532                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
6533                     mResolveActivity.exported = true;
6534                     mResolveActivity.enabled = true;
6535                     mResolveInfo.activityInfo = mResolveActivity;
6536                     mResolveInfo.priority = 0;
6537                     mResolveInfo.preferredOrder = 0;
6538                     mResolveInfo.match = 0;
6539                     mResolveComponentName = new ComponentName(
6540                             mAndroidApplication.packageName, mResolveActivity.name);
6541                 }
6542             }
6543         }
6544
6545         if (DEBUG_PACKAGE_SCANNING) {
6546             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6547                 Log.d(TAG, "Scanning package " + pkg.packageName);
6548         }
6549
6550         if (mPackages.containsKey(pkg.packageName)
6551                 || mSharedLibraries.containsKey(pkg.packageName)) {
6552             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6553                     "Application package " + pkg.packageName
6554                     + " already installed.  Skipping duplicate.");
6555         }
6556
6557         // If we're only installing presumed-existing packages, require that the
6558         // scanned APK is both already known and at the path previously established
6559         // for it.  Previously unknown packages we pick up normally, but if we have an
6560         // a priori expectation about this package's install presence, enforce it.
6561         // With a singular exception for new system packages. When an OTA contains
6562         // a new system package, we allow the codepath to change from a system location
6563         // to the user-installed location. If we don't allow this change, any newer,
6564         // user-installed version of the application will be ignored.
6565         if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
6566             if (mExpectingBetter.containsKey(pkg.packageName)) {
6567                 logCriticalInfo(Log.WARN,
6568                         "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
6569             } else {
6570                 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
6571                 if (known != null) {
6572                     if (DEBUG_PACKAGE_SCANNING) {
6573                         Log.d(TAG, "Examining " + pkg.codePath
6574                                 + " and requiring known paths " + known.codePathString
6575                                 + " & " + known.resourcePathString);
6576                     }
6577                     if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
6578                             || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
6579                         throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
6580                                 "Application package " + pkg.packageName
6581                                 + " found at " + pkg.applicationInfo.getCodePath()
6582                                 + " but expected at " + known.codePathString + "; ignoring.");
6583                     }
6584                 }
6585             }
6586         }
6587
6588         // Initialize package source and resource directories
6589         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
6590         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
6591
6592         SharedUserSetting suid = null;
6593         PackageSetting pkgSetting = null;
6594
6595         if (!isSystemApp(pkg)) {
6596             // Only system apps can use these features.
6597             pkg.mOriginalPackages = null;
6598             pkg.mRealPackage = null;
6599             pkg.mAdoptPermissions = null;
6600         }
6601
6602         // writer
6603         synchronized (mPackages) {
6604             if (pkg.mSharedUserId != null) {
6605                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
6606                 if (suid == null) {
6607                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6608                             "Creating application package " + pkg.packageName
6609                             + " for shared user failed");
6610                 }
6611                 if (DEBUG_PACKAGE_SCANNING) {
6612                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6613                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
6614                                 + "): packages=" + suid.packages);
6615                 }
6616             }
6617
6618             // Check if we are renaming from an original package name.
6619             PackageSetting origPackage = null;
6620             String realName = null;
6621             if (pkg.mOriginalPackages != null) {
6622                 // This package may need to be renamed to a previously
6623                 // installed name.  Let's check on that...
6624                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
6625                 if (pkg.mOriginalPackages.contains(renamed)) {
6626                     // This package had originally been installed as the
6627                     // original name, and we have already taken care of
6628                     // transitioning to the new one.  Just update the new
6629                     // one to continue using the old name.
6630                     realName = pkg.mRealPackage;
6631                     if (!pkg.packageName.equals(renamed)) {
6632                         // Callers into this function may have already taken
6633                         // care of renaming the package; only do it here if
6634                         // it is not already done.
6635                         pkg.setPackageName(renamed);
6636                     }
6637
6638                 } else {
6639                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
6640                         if ((origPackage = mSettings.peekPackageLPr(
6641                                 pkg.mOriginalPackages.get(i))) != null) {
6642                             // We do have the package already installed under its
6643                             // original name...  should we use it?
6644                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
6645                                 // New package is not compatible with original.
6646                                 origPackage = null;
6647                                 continue;
6648                             } else if (origPackage.sharedUser != null) {
6649                                 // Make sure uid is compatible between packages.
6650                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
6651                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
6652                                             + " to " + pkg.packageName + ": old uid "
6653                                             + origPackage.sharedUser.name
6654                                             + " differs from " + pkg.mSharedUserId);
6655                                     origPackage = null;
6656                                     continue;
6657                                 }
6658                             } else {
6659                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
6660                                         + pkg.packageName + " to old name " + origPackage.name);
6661                             }
6662                             break;
6663                         }
6664                     }
6665                 }
6666             }
6667
6668             if (mTransferedPackages.contains(pkg.packageName)) {
6669                 Slog.w(TAG, "Package " + pkg.packageName
6670                         + " was transferred to another, but its .apk remains");
6671             }
6672
6673             // Just create the setting, don't add it yet. For already existing packages
6674             // the PkgSetting exists already and doesn't have to be created.
6675             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
6676                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
6677                     pkg.applicationInfo.primaryCpuAbi,
6678                     pkg.applicationInfo.secondaryCpuAbi,
6679                     pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
6680                     user, false);
6681             if (pkgSetting == null) {
6682                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6683                         "Creating application package " + pkg.packageName + " failed");
6684             }
6685
6686             if (pkgSetting.origPackage != null) {
6687                 // If we are first transitioning from an original package,
6688                 // fix up the new package's name now.  We need to do this after
6689                 // looking up the package under its new name, so getPackageLP
6690                 // can take care of fiddling things correctly.
6691                 pkg.setPackageName(origPackage.name);
6692
6693                 // File a report about this.
6694                 String msg = "New package " + pkgSetting.realName
6695                         + " renamed to replace old package " + pkgSetting.name;
6696                 reportSettingsProblem(Log.WARN, msg);
6697
6698                 // Make a note of it.
6699                 mTransferedPackages.add(origPackage.name);
6700
6701                 // No longer need to retain this.
6702                 pkgSetting.origPackage = null;
6703             }
6704
6705             if (realName != null) {
6706                 // Make a note of it.
6707                 mTransferedPackages.add(pkg.packageName);
6708             }
6709
6710             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
6711                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
6712             }
6713
6714             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6715                 // Check all shared libraries and map to their actual file path.
6716                 // We only do this here for apps not on a system dir, because those
6717                 // are the only ones that can fail an install due to this.  We
6718                 // will take care of the system apps by updating all of their
6719                 // library paths after the scan is done.
6720                 updateSharedLibrariesLPw(pkg, null);
6721             }
6722
6723             if (mFoundPolicyFile) {
6724                 SELinuxMMAC.assignSeinfoValue(pkg);
6725             }
6726
6727             pkg.applicationInfo.uid = pkgSetting.appId;
6728             pkg.mExtras = pkgSetting;
6729             if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
6730                 if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
6731                     // We just determined the app is signed correctly, so bring
6732                     // over the latest parsed certs.
6733                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
6734                 } else {
6735                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6736                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6737                                 "Package " + pkg.packageName + " upgrade keys do not match the "
6738                                 + "previously installed version");
6739                     } else {
6740                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
6741                         String msg = "System package " + pkg.packageName
6742                             + " signature changed; retaining data.";
6743                         reportSettingsProblem(Log.WARN, msg);
6744                     }
6745                 }
6746             } else {
6747                 try {
6748                     verifySignaturesLP(pkgSetting, pkg);
6749                     // We just determined the app is signed correctly, so bring
6750                     // over the latest parsed certs.
6751                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
6752                 } catch (PackageManagerException e) {
6753                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6754                         throw e;
6755                     }
6756                     // The signature has changed, but this package is in the system
6757                     // image...  let's recover!
6758                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
6759                     // However...  if this package is part of a shared user, but it
6760                     // doesn't match the signature of the shared user, let's fail.
6761                     // What this means is that you can't change the signatures
6762                     // associated with an overall shared user, which doesn't seem all
6763                     // that unreasonable.
6764                     if (pkgSetting.sharedUser != null) {
6765                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
6766                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
6767                             throw new PackageManagerException(
6768                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
6769                                             "Signature mismatch for shared user : "
6770                                             + pkgSetting.sharedUser);
6771                         }
6772                     }
6773                     // File a report about this.
6774                     String msg = "System package " + pkg.packageName
6775                         + " signature changed; retaining data.";
6776                     reportSettingsProblem(Log.WARN, msg);
6777                 }
6778             }
6779             // Verify that this new package doesn't have any content providers
6780             // that conflict with existing packages.  Only do this if the
6781             // package isn't already installed, since we don't want to break
6782             // things that are installed.
6783             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
6784                 final int N = pkg.providers.size();
6785                 int i;
6786                 for (i=0; i<N; i++) {
6787                     PackageParser.Provider p = pkg.providers.get(i);
6788                     if (p.info.authority != null) {
6789                         String names[] = p.info.authority.split(";");
6790                         for (int j = 0; j < names.length; j++) {
6791                             if (mProvidersByAuthority.containsKey(names[j])) {
6792                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6793                                 final String otherPackageName =
6794                                         ((other != null && other.getComponentName() != null) ?
6795                                                 other.getComponentName().getPackageName() : "?");
6796                                 throw new PackageManagerException(
6797                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
6798                                                 "Can't install because provider name " + names[j]
6799                                                 + " (in package " + pkg.applicationInfo.packageName
6800                                                 + ") is already used by " + otherPackageName);
6801                             }
6802                         }
6803                     }
6804                 }
6805             }
6806
6807             if (pkg.mAdoptPermissions != null) {
6808                 // This package wants to adopt ownership of permissions from
6809                 // another package.
6810                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
6811                     final String origName = pkg.mAdoptPermissions.get(i);
6812                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
6813                     if (orig != null) {
6814                         if (verifyPackageUpdateLPr(orig, pkg)) {
6815                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
6816                                     + pkg.packageName);
6817                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
6818                         }
6819                     }
6820                 }
6821             }
6822         }
6823
6824         final String pkgName = pkg.packageName;
6825
6826         final long scanFileTime = scanFile.lastModified();
6827         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
6828         pkg.applicationInfo.processName = fixProcessName(
6829                 pkg.applicationInfo.packageName,
6830                 pkg.applicationInfo.processName,
6831                 pkg.applicationInfo.uid);
6832
6833         File dataPath;
6834         if (mPlatformPackage == pkg) {
6835             // The system package is special.
6836             dataPath = new File(Environment.getDataDirectory(), "system");
6837
6838             pkg.applicationInfo.dataDir = dataPath.getPath();
6839
6840         } else {
6841             // This is a normal package, need to make its data directory.
6842             dataPath = Environment.getDataUserPackageDirectory(pkg.volumeUuid,
6843                     UserHandle.USER_OWNER, pkg.packageName);
6844
6845             boolean uidError = false;
6846             if (dataPath.exists()) {
6847                 int currentUid = 0;
6848                 try {
6849                     StructStat stat = Os.stat(dataPath.getPath());
6850                     currentUid = stat.st_uid;
6851                 } catch (ErrnoException e) {
6852                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
6853                 }
6854
6855                 // If we have mismatched owners for the data path, we have a problem.
6856                 if (currentUid != pkg.applicationInfo.uid) {
6857                     boolean recovered = false;
6858                     if (currentUid == 0) {
6859                         // The directory somehow became owned by root.  Wow.
6860                         // This is probably because the system was stopped while
6861                         // installd was in the middle of messing with its libs
6862                         // directory.  Ask installd to fix that.
6863                         int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName,
6864                                 pkg.applicationInfo.uid, pkg.applicationInfo.uid);
6865                         if (ret >= 0) {
6866                             recovered = true;
6867                             String msg = "Package " + pkg.packageName
6868                                     + " unexpectedly changed to uid 0; recovered to " +
6869                                     + pkg.applicationInfo.uid;
6870                             reportSettingsProblem(Log.WARN, msg);
6871                         }
6872                     }
6873                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6874                             || (scanFlags&SCAN_BOOTING) != 0)) {
6875                         // If this is a system app, we can at least delete its
6876                         // current data so the application will still work.
6877                         int ret = removeDataDirsLI(pkg.volumeUuid, pkgName);
6878                         if (ret >= 0) {
6879                             // TODO: Kill the processes first
6880                             // Old data gone!
6881                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6882                                     ? "System package " : "Third party package ";
6883                             String msg = prefix + pkg.packageName
6884                                     + " has changed from uid: "
6885                                     + currentUid + " to "
6886                                     + pkg.applicationInfo.uid + "; old data erased";
6887                             reportSettingsProblem(Log.WARN, msg);
6888                             recovered = true;
6889
6890                             // And now re-install the app.
6891                             ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6892                                     pkg.applicationInfo.seinfo);
6893                             if (ret == -1) {
6894                                 // Ack should not happen!
6895                                 msg = prefix + pkg.packageName
6896                                         + " could not have data directory re-created after delete.";
6897                                 reportSettingsProblem(Log.WARN, msg);
6898                                 throw new PackageManagerException(
6899                                         INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
6900                             }
6901                         }
6902                         if (!recovered) {
6903                             mHasSystemUidErrors = true;
6904                         }
6905                     } else if (!recovered) {
6906                         // If we allow this install to proceed, we will be broken.
6907                         // Abort, abort!
6908                         throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
6909                                 "scanPackageLI");
6910                     }
6911                     if (!recovered) {
6912                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
6913                             + pkg.applicationInfo.uid + "/fs_"
6914                             + currentUid;
6915                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
6916                         pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
6917                         String msg = "Package " + pkg.packageName
6918                                 + " has mismatched uid: "
6919                                 + currentUid + " on disk, "
6920                                 + pkg.applicationInfo.uid + " in settings";
6921                         // writer
6922                         synchronized (mPackages) {
6923                             mSettings.mReadMessages.append(msg);
6924                             mSettings.mReadMessages.append('\n');
6925                             uidError = true;
6926                             if (!pkgSetting.uidError) {
6927                                 reportSettingsProblem(Log.ERROR, msg);
6928                             }
6929                         }
6930                     }
6931                 }
6932                 pkg.applicationInfo.dataDir = dataPath.getPath();
6933                 if (mShouldRestoreconData) {
6934                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
6935                     mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName,
6936                             pkg.applicationInfo.seinfo, pkg.applicationInfo.uid);
6937                 }
6938             } else {
6939                 if (DEBUG_PACKAGE_SCANNING) {
6940                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6941                         Log.v(TAG, "Want this data dir: " + dataPath);
6942                 }
6943                 //invoke installer to do the actual installation
6944                 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6945                         pkg.applicationInfo.seinfo);
6946                 if (ret < 0) {
6947                     // Error from installer
6948                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6949                             "Unable to create data dirs [errorCode=" + ret + "]");
6950                 }
6951
6952                 if (dataPath.exists()) {
6953                     pkg.applicationInfo.dataDir = dataPath.getPath();
6954                 } else {
6955                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
6956                     pkg.applicationInfo.dataDir = null;
6957                 }
6958             }
6959
6960             pkgSetting.uidError = uidError;
6961         }
6962
6963         final String path = scanFile.getPath();
6964         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
6965
6966         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
6967             derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
6968
6969             // Some system apps still use directory structure for native libraries
6970             // in which case we might end up not detecting abi solely based on apk
6971             // structure. Try to detect abi based on directory structure.
6972             if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
6973                     pkg.applicationInfo.primaryCpuAbi == null) {
6974                 setBundledAppAbisAndRoots(pkg, pkgSetting);
6975                 setNativeLibraryPaths(pkg);
6976             }
6977
6978         } else {
6979             if ((scanFlags & SCAN_MOVE) != 0) {
6980                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
6981                 // but we already have this packages package info in the PackageSetting. We just
6982                 // use that and derive the native library path based on the new codepath.
6983                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
6984                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
6985             }
6986
6987             // Set native library paths again. For moves, the path will be updated based on the
6988             // ABIs we've determined above. For non-moves, the path will be updated based on the
6989             // ABIs we determined during compilation, but the path will depend on the final
6990             // package path (after the rename away from the stage path).
6991             setNativeLibraryPaths(pkg);
6992         }
6993
6994         if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
6995         final int[] userIds = sUserManager.getUserIds();
6996         synchronized (mInstallLock) {
6997             // Make sure all user data directories are ready to roll; we're okay
6998             // if they already exist
6999             if (!TextUtils.isEmpty(pkg.volumeUuid)) {
7000                 for (int userId : userIds) {
7001                     if (userId != 0) {
7002                         mInstaller.createUserData(pkg.volumeUuid, pkg.packageName,
7003                                 UserHandle.getUid(userId, pkg.applicationInfo.uid), userId,
7004                                 pkg.applicationInfo.seinfo);
7005                     }
7006                 }
7007             }
7008
7009             // Create a native library symlink only if we have native libraries
7010             // and if the native libraries are 32 bit libraries. We do not provide
7011             // this symlink for 64 bit libraries.
7012             if (pkg.applicationInfo.primaryCpuAbi != null &&
7013                     !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
7014                 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
7015                 for (int userId : userIds) {
7016                     if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
7017                             nativeLibPath, userId) < 0) {
7018                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
7019                                 "Failed linking native library dir (user=" + userId + ")");
7020                     }
7021                 }
7022             }
7023         }
7024
7025         // This is a special case for the "system" package, where the ABI is
7026         // dictated by the zygote configuration (and init.rc). We should keep track
7027         // of this ABI so that we can deal with "normal" applications that run under
7028         // the same UID correctly.
7029         if (mPlatformPackage == pkg) {
7030             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
7031                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
7032         }
7033
7034         // If there's a mismatch between the abi-override in the package setting
7035         // and the abiOverride specified for the install. Warn about this because we
7036         // would've already compiled the app without taking the package setting into
7037         // account.
7038         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
7039             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
7040                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
7041                         " for package: " + pkg.packageName);
7042             }
7043         }
7044
7045         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7046         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7047         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
7048
7049         // Copy the derived override back to the parsed package, so that we can
7050         // update the package settings accordingly.
7051         pkg.cpuAbiOverride = cpuAbiOverride;
7052
7053         if (DEBUG_ABI_SELECTION) {
7054             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
7055                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
7056                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
7057         }
7058
7059         // Push the derived path down into PackageSettings so we know what to
7060         // clean up at uninstall time.
7061         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
7062
7063         if (DEBUG_ABI_SELECTION) {
7064             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
7065                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
7066                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
7067         }
7068
7069         if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
7070             // We don't do this here during boot because we can do it all
7071             // at once after scanning all existing packages.
7072             //
7073             // We also do this *before* we perform dexopt on this package, so that
7074             // we can avoid redundant dexopts, and also to make sure we've got the
7075             // code and package path correct.
7076             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
7077                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, true /* boot complete */);
7078         }
7079
7080         if ((scanFlags & SCAN_NO_DEX) == 0) {
7081             int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
7082                     forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */,
7083                     (scanFlags & SCAN_BOOTING) == 0);
7084             if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
7085                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
7086             }
7087         }
7088         if (mFactoryTest && pkg.requestedPermissions.contains(
7089                 android.Manifest.permission.FACTORY_TEST)) {
7090             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
7091         }
7092
7093         ArrayList<PackageParser.Package> clientLibPkgs = null;
7094
7095         // writer
7096         synchronized (mPackages) {
7097             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7098                 // Only system apps can add new shared libraries.
7099                 if (pkg.libraryNames != null) {
7100                     for (int i=0; i<pkg.libraryNames.size(); i++) {
7101                         String name = pkg.libraryNames.get(i);
7102                         boolean allowed = false;
7103                         if (pkg.isUpdatedSystemApp()) {
7104                             // New library entries can only be added through the
7105                             // system image.  This is important to get rid of a lot
7106                             // of nasty edge cases: for example if we allowed a non-
7107                             // system update of the app to add a library, then uninstalling
7108                             // the update would make the library go away, and assumptions
7109                             // we made such as through app install filtering would now
7110                             // have allowed apps on the device which aren't compatible
7111                             // with it.  Better to just have the restriction here, be
7112                             // conservative, and create many fewer cases that can negatively
7113                             // impact the user experience.
7114                             final PackageSetting sysPs = mSettings
7115                                     .getDisabledSystemPkgLPr(pkg.packageName);
7116                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
7117                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
7118                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
7119                                         allowed = true;
7120                                         allowed = true;
7121                                         break;
7122                                     }
7123                                 }
7124                             }
7125                         } else {
7126                             allowed = true;
7127                         }
7128                         if (allowed) {
7129                             if (!mSharedLibraries.containsKey(name)) {
7130                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
7131                             } else if (!name.equals(pkg.packageName)) {
7132                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
7133                                         + name + " already exists; skipping");
7134                             }
7135                         } else {
7136                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
7137                                     + name + " that is not declared on system image; skipping");
7138                         }
7139                     }
7140                     if ((scanFlags&SCAN_BOOTING) == 0) {
7141                         // If we are not booting, we need to update any applications
7142                         // that are clients of our shared library.  If we are booting,
7143                         // this will all be done once the scan is complete.
7144                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
7145                     }
7146                 }
7147             }
7148         }
7149
7150         // We also need to dexopt any apps that are dependent on this library.  Note that
7151         // if these fail, we should abort the install since installing the library will
7152         // result in some apps being broken.
7153         if (clientLibPkgs != null) {
7154             if ((scanFlags & SCAN_NO_DEX) == 0) {
7155                 for (int i = 0; i < clientLibPkgs.size(); i++) {
7156                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
7157                     int result = mPackageDexOptimizer.performDexOpt(clientPkg,
7158                             null /* instruction sets */, forceDex,
7159                             (scanFlags & SCAN_DEFER_DEX) != 0, false,
7160                             (scanFlags & SCAN_BOOTING) == 0);
7161                     if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
7162                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
7163                                 "scanPackageLI failed to dexopt clientLibPkgs");
7164                     }
7165                 }
7166             }
7167         }
7168
7169         // Request the ActivityManager to kill the process(only for existing packages)
7170         // so that we do not end up in a confused state while the user is still using the older
7171         // version of the application while the new one gets installed.
7172         if ((scanFlags & SCAN_REPLACING) != 0) {
7173             killApplication(pkg.applicationInfo.packageName,
7174                         pkg.applicationInfo.uid, "replace pkg");
7175         }
7176
7177         // Also need to kill any apps that are dependent on the library.
7178         if (clientLibPkgs != null) {
7179             for (int i=0; i<clientLibPkgs.size(); i++) {
7180                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
7181                 killApplication(clientPkg.applicationInfo.packageName,
7182                         clientPkg.applicationInfo.uid, "update lib");
7183             }
7184         }
7185
7186         // Make sure we're not adding any bogus keyset info
7187         KeySetManagerService ksms = mSettings.mKeySetManagerService;
7188         ksms.assertScannedPackageValid(pkg);
7189
7190         // writer
7191         synchronized (mPackages) {
7192             // We don't expect installation to fail beyond this point
7193
7194             // Add the new setting to mSettings
7195             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
7196             // Add the new setting to mPackages
7197             mPackages.put(pkg.applicationInfo.packageName, pkg);
7198             // Make sure we don't accidentally delete its data.
7199             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
7200             while (iter.hasNext()) {
7201                 PackageCleanItem item = iter.next();
7202                 if (pkgName.equals(item.packageName)) {
7203                     iter.remove();
7204                 }
7205             }
7206
7207             // Take care of first install / last update times.
7208             if (currentTime != 0) {
7209                 if (pkgSetting.firstInstallTime == 0) {
7210                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
7211                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
7212                     pkgSetting.lastUpdateTime = currentTime;
7213                 }
7214             } else if (pkgSetting.firstInstallTime == 0) {
7215                 // We need *something*.  Take time time stamp of the file.
7216                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
7217             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
7218                 if (scanFileTime != pkgSetting.timeStamp) {
7219                     // A package on the system image has changed; consider this
7220                     // to be an update.
7221                     pkgSetting.lastUpdateTime = scanFileTime;
7222                 }
7223             }
7224
7225             // Add the package's KeySets to the global KeySetManagerService
7226             ksms.addScannedPackageLPw(pkg);
7227
7228             int N = pkg.providers.size();
7229             StringBuilder r = null;
7230             int i;
7231             for (i=0; i<N; i++) {
7232                 PackageParser.Provider p = pkg.providers.get(i);
7233                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
7234                         p.info.processName, pkg.applicationInfo.uid);
7235                 mProviders.addProvider(p);
7236                 p.syncable = p.info.isSyncable;
7237                 if (p.info.authority != null) {
7238                     String names[] = p.info.authority.split(";");
7239                     p.info.authority = null;
7240                     for (int j = 0; j < names.length; j++) {
7241                         if (j == 1 && p.syncable) {
7242                             // We only want the first authority for a provider to possibly be
7243                             // syncable, so if we already added this provider using a different
7244                             // authority clear the syncable flag. We copy the provider before
7245                             // changing it because the mProviders object contains a reference
7246                             // to a provider that we don't want to change.
7247                             // Only do this for the second authority since the resulting provider
7248                             // object can be the same for all future authorities for this provider.
7249                             p = new PackageParser.Provider(p);
7250                             p.syncable = false;
7251                         }
7252                         if (!mProvidersByAuthority.containsKey(names[j])) {
7253                             mProvidersByAuthority.put(names[j], p);
7254                             if (p.info.authority == null) {
7255                                 p.info.authority = names[j];
7256                             } else {
7257                                 p.info.authority = p.info.authority + ";" + names[j];
7258                             }
7259                             if (DEBUG_PACKAGE_SCANNING) {
7260                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7261                                     Log.d(TAG, "Registered content provider: " + names[j]
7262                                             + ", className = " + p.info.name + ", isSyncable = "
7263                                             + p.info.isSyncable);
7264                             }
7265                         } else {
7266                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7267                             Slog.w(TAG, "Skipping provider name " + names[j] +
7268                                     " (in package " + pkg.applicationInfo.packageName +
7269                                     "): name already used by "
7270                                     + ((other != null && other.getComponentName() != null)
7271                                             ? other.getComponentName().getPackageName() : "?"));
7272                         }
7273                     }
7274                 }
7275                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7276                     if (r == null) {
7277                         r = new StringBuilder(256);
7278                     } else {
7279                         r.append(' ');
7280                     }
7281                     r.append(p.info.name);
7282                 }
7283             }
7284             if (r != null) {
7285                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
7286             }
7287
7288             N = pkg.services.size();
7289             r = null;
7290             for (i=0; i<N; i++) {
7291                 PackageParser.Service s = pkg.services.get(i);
7292                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
7293                         s.info.processName, pkg.applicationInfo.uid);
7294                 mServices.addService(s);
7295                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7296                     if (r == null) {
7297                         r = new StringBuilder(256);
7298                     } else {
7299                         r.append(' ');
7300                     }
7301                     r.append(s.info.name);
7302                 }
7303             }
7304             if (r != null) {
7305                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
7306             }
7307
7308             N = pkg.receivers.size();
7309             r = null;
7310             for (i=0; i<N; i++) {
7311                 PackageParser.Activity a = pkg.receivers.get(i);
7312                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7313                         a.info.processName, pkg.applicationInfo.uid);
7314                 mReceivers.addActivity(a, "receiver");
7315                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7316                     if (r == null) {
7317                         r = new StringBuilder(256);
7318                     } else {
7319                         r.append(' ');
7320                     }
7321                     r.append(a.info.name);
7322                 }
7323             }
7324             if (r != null) {
7325                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
7326             }
7327
7328             N = pkg.activities.size();
7329             r = null;
7330             for (i=0; i<N; i++) {
7331                 PackageParser.Activity a = pkg.activities.get(i);
7332                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7333                         a.info.processName, pkg.applicationInfo.uid);
7334                 mActivities.addActivity(a, "activity");
7335                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7336                     if (r == null) {
7337                         r = new StringBuilder(256);
7338                     } else {
7339                         r.append(' ');
7340                     }
7341                     r.append(a.info.name);
7342                 }
7343             }
7344             if (r != null) {
7345                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
7346             }
7347
7348             N = pkg.permissionGroups.size();
7349             r = null;
7350             for (i=0; i<N; i++) {
7351                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
7352                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
7353                 if (cur == null) {
7354                     mPermissionGroups.put(pg.info.name, pg);
7355                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7356                         if (r == null) {
7357                             r = new StringBuilder(256);
7358                         } else {
7359                             r.append(' ');
7360                         }
7361                         r.append(pg.info.name);
7362                     }
7363                 } else {
7364                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
7365                             + pg.info.packageName + " ignored: original from "
7366                             + cur.info.packageName);
7367                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7368                         if (r == null) {
7369                             r = new StringBuilder(256);
7370                         } else {
7371                             r.append(' ');
7372                         }
7373                         r.append("DUP:");
7374                         r.append(pg.info.name);
7375                     }
7376                 }
7377             }
7378             if (r != null) {
7379                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
7380             }
7381
7382             N = pkg.permissions.size();
7383             r = null;
7384             for (i=0; i<N; i++) {
7385                 PackageParser.Permission p = pkg.permissions.get(i);
7386
7387                 // Assume by default that we did not install this permission into the system.
7388                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
7389
7390                 // Now that permission groups have a special meaning, we ignore permission
7391                 // groups for legacy apps to prevent unexpected behavior. In particular,
7392                 // permissions for one app being granted to someone just becuase they happen
7393                 // to be in a group defined by another app (before this had no implications).
7394                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
7395                     p.group = mPermissionGroups.get(p.info.group);
7396                     // Warn for a permission in an unknown group.
7397                     if (p.info.group != null && p.group == null) {
7398                         Slog.w(TAG, "Permission " + p.info.name + " from package "
7399                                 + p.info.packageName + " in an unknown group " + p.info.group);
7400                     }
7401                 }
7402
7403                 ArrayMap<String, BasePermission> permissionMap =
7404                         p.tree ? mSettings.mPermissionTrees
7405                                 : mSettings.mPermissions;
7406                 BasePermission bp = permissionMap.get(p.info.name);
7407
7408                 // Allow system apps to redefine non-system permissions
7409                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
7410                     final boolean currentOwnerIsSystem = (bp.perm != null
7411                             && isSystemApp(bp.perm.owner));
7412                     if (isSystemApp(p.owner)) {
7413                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
7414                             // It's a built-in permission and no owner, take ownership now
7415                             bp.packageSetting = pkgSetting;
7416                             bp.perm = p;
7417                             bp.uid = pkg.applicationInfo.uid;
7418                             bp.sourcePackage = p.info.packageName;
7419                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7420                         } else if (!currentOwnerIsSystem) {
7421                             String msg = "New decl " + p.owner + " of permission  "
7422                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
7423                             reportSettingsProblem(Log.WARN, msg);
7424                             bp = null;
7425                         }
7426                     }
7427                 }
7428
7429                 if (bp == null) {
7430                     bp = new BasePermission(p.info.name, p.info.packageName,
7431                             BasePermission.TYPE_NORMAL);
7432                     permissionMap.put(p.info.name, bp);
7433                 }
7434
7435                 if (bp.perm == null) {
7436                     if (bp.sourcePackage == null
7437                             || bp.sourcePackage.equals(p.info.packageName)) {
7438                         BasePermission tree = findPermissionTreeLP(p.info.name);
7439                         if (tree == null
7440                                 || tree.sourcePackage.equals(p.info.packageName)) {
7441                             bp.packageSetting = pkgSetting;
7442                             bp.perm = p;
7443                             bp.uid = pkg.applicationInfo.uid;
7444                             bp.sourcePackage = p.info.packageName;
7445                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7446                             if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7447                                 if (r == null) {
7448                                     r = new StringBuilder(256);
7449                                 } else {
7450                                     r.append(' ');
7451                                 }
7452                                 r.append(p.info.name);
7453                             }
7454                         } else {
7455                             Slog.w(TAG, "Permission " + p.info.name + " from package "
7456                                     + p.info.packageName + " ignored: base tree "
7457                                     + tree.name + " is from package "
7458                                     + tree.sourcePackage);
7459                         }
7460                     } else {
7461                         Slog.w(TAG, "Permission " + p.info.name + " from package "
7462                                 + p.info.packageName + " ignored: original from "
7463                                 + bp.sourcePackage);
7464                     }
7465                 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7466                     if (r == null) {
7467                         r = new StringBuilder(256);
7468                     } else {
7469                         r.append(' ');
7470                     }
7471                     r.append("DUP:");
7472                     r.append(p.info.name);
7473                 }
7474                 if (bp.perm == p) {
7475                     bp.protectionLevel = p.info.protectionLevel;
7476                 }
7477             }
7478
7479             if (r != null) {
7480                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
7481             }
7482
7483             N = pkg.instrumentation.size();
7484             r = null;
7485             for (i=0; i<N; i++) {
7486                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7487                 a.info.packageName = pkg.applicationInfo.packageName;
7488                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
7489                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
7490                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
7491                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
7492                 a.info.dataDir = pkg.applicationInfo.dataDir;
7493
7494                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
7495                 // need other information about the application, like the ABI and what not ?
7496                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
7497                 mInstrumentation.put(a.getComponentName(), a);
7498                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7499                     if (r == null) {
7500                         r = new StringBuilder(256);
7501                     } else {
7502                         r.append(' ');
7503                     }
7504                     r.append(a.info.name);
7505                 }
7506             }
7507             if (r != null) {
7508                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
7509             }
7510
7511             if (pkg.protectedBroadcasts != null) {
7512                 N = pkg.protectedBroadcasts.size();
7513                 for (i=0; i<N; i++) {
7514                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
7515                 }
7516             }
7517
7518             pkgSetting.setTimeStamp(scanFileTime);
7519
7520             // Create idmap files for pairs of (packages, overlay packages).
7521             // Note: "android", ie framework-res.apk, is handled by native layers.
7522             if (pkg.mOverlayTarget != null) {
7523                 // This is an overlay package.
7524                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
7525                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
7526                         mOverlays.put(pkg.mOverlayTarget,
7527                                 new ArrayMap<String, PackageParser.Package>());
7528                     }
7529                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
7530                     map.put(pkg.packageName, pkg);
7531                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
7532                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
7533                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7534                                 "scanPackageLI failed to createIdmap");
7535                     }
7536                 }
7537             } else if (mOverlays.containsKey(pkg.packageName) &&
7538                     !pkg.packageName.equals("android")) {
7539                 // This is a regular package, with one or more known overlay packages.
7540                 createIdmapsForPackageLI(pkg);
7541             }
7542         }
7543
7544         return pkg;
7545     }
7546
7547     /**
7548      * Derive the ABI of a non-system package located at {@code scanFile}. This information
7549      * is derived purely on the basis of the contents of {@code scanFile} and
7550      * {@code cpuAbiOverride}.
7551      *
7552      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
7553      */
7554     public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
7555                                  String cpuAbiOverride, boolean extractLibs)
7556             throws PackageManagerException {
7557         // TODO: We can probably be smarter about this stuff. For installed apps,
7558         // we can calculate this information at install time once and for all. For
7559         // system apps, we can probably assume that this information doesn't change
7560         // after the first boot scan. As things stand, we do lots of unnecessary work.
7561
7562         // Give ourselves some initial paths; we'll come back for another
7563         // pass once we've determined ABI below.
7564         setNativeLibraryPaths(pkg);
7565
7566         // We would never need to extract libs for forward-locked and external packages,
7567         // since the container service will do it for us. We shouldn't attempt to
7568         // extract libs from system app when it was not updated.
7569         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
7570                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
7571             extractLibs = false;
7572         }
7573
7574         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
7575         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
7576
7577         NativeLibraryHelper.Handle handle = null;
7578         try {
7579             handle = NativeLibraryHelper.Handle.create(scanFile);
7580             // TODO(multiArch): This can be null for apps that didn't go through the
7581             // usual installation process. We can calculate it again, like we
7582             // do during install time.
7583             //
7584             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
7585             // unnecessary.
7586             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
7587
7588             // Null out the abis so that they can be recalculated.
7589             pkg.applicationInfo.primaryCpuAbi = null;
7590             pkg.applicationInfo.secondaryCpuAbi = null;
7591             if (isMultiArch(pkg.applicationInfo)) {
7592                 // Warn if we've set an abiOverride for multi-lib packages..
7593                 // By definition, we need to copy both 32 and 64 bit libraries for
7594                 // such packages.
7595                 if (pkg.cpuAbiOverride != null
7596                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
7597                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
7598                 }
7599
7600                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
7601                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
7602                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
7603                     if (extractLibs) {
7604                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7605                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
7606                                 useIsaSpecificSubdirs);
7607                     } else {
7608                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
7609                     }
7610                 }
7611
7612                 maybeThrowExceptionForMultiArchCopy(
7613                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
7614
7615                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
7616                     if (extractLibs) {
7617                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7618                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
7619                                 useIsaSpecificSubdirs);
7620                     } else {
7621                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
7622                     }
7623                 }
7624
7625                 maybeThrowExceptionForMultiArchCopy(
7626                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
7627
7628                 if (abi64 >= 0) {
7629                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
7630                 }
7631
7632                 if (abi32 >= 0) {
7633                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
7634                     if (abi64 >= 0) {
7635                         pkg.applicationInfo.secondaryCpuAbi = abi;
7636                     } else {
7637                         pkg.applicationInfo.primaryCpuAbi = abi;
7638                     }
7639                 }
7640             } else {
7641                 String[] abiList = (cpuAbiOverride != null) ?
7642                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
7643
7644                 // Enable gross and lame hacks for apps that are built with old
7645                 // SDK tools. We must scan their APKs for renderscript bitcode and
7646                 // not launch them if it's present. Don't bother checking on devices
7647                 // that don't have 64 bit support.
7648                 boolean needsRenderScriptOverride = false;
7649                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
7650                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
7651                     abiList = Build.SUPPORTED_32_BIT_ABIS;
7652                     needsRenderScriptOverride = true;
7653                 }
7654
7655                 final int copyRet;
7656                 if (extractLibs) {
7657                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7658                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
7659                 } else {
7660                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
7661                 }
7662
7663                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
7664                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
7665                             "Error unpackaging native libs for app, errorCode=" + copyRet);
7666                 }
7667
7668                 if (copyRet >= 0) {
7669                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
7670                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
7671                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
7672                 } else if (needsRenderScriptOverride) {
7673                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
7674                 }
7675             }
7676         } catch (IOException ioe) {
7677             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
7678         } finally {
7679             IoUtils.closeQuietly(handle);
7680         }
7681
7682         // Now that we've calculated the ABIs and determined if it's an internal app,
7683         // we will go ahead and populate the nativeLibraryPath.
7684         setNativeLibraryPaths(pkg);
7685     }
7686
7687     /**
7688      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
7689      * i.e, so that all packages can be run inside a single process if required.
7690      *
7691      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
7692      * this function will either try and make the ABI for all packages in {@code packagesForUser}
7693      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
7694      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
7695      * updating a package that belongs to a shared user.
7696      *
7697      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
7698      * adds unnecessary complexity.
7699      */
7700     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
7701             PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt,
7702             boolean bootComplete) {
7703         String requiredInstructionSet = null;
7704         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
7705             requiredInstructionSet = VMRuntime.getInstructionSet(
7706                      scannedPackage.applicationInfo.primaryCpuAbi);
7707         }
7708
7709         PackageSetting requirer = null;
7710         for (PackageSetting ps : packagesForUser) {
7711             // If packagesForUser contains scannedPackage, we skip it. This will happen
7712             // when scannedPackage is an update of an existing package. Without this check,
7713             // we will never be able to change the ABI of any package belonging to a shared
7714             // user, even if it's compatible with other packages.
7715             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
7716                 if (ps.primaryCpuAbiString == null) {
7717                     continue;
7718                 }
7719
7720                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
7721                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
7722                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
7723                     // this but there's not much we can do.
7724                     String errorMessage = "Instruction set mismatch, "
7725                             + ((requirer == null) ? "[caller]" : requirer)
7726                             + " requires " + requiredInstructionSet + " whereas " + ps
7727                             + " requires " + instructionSet;
7728                     Slog.w(TAG, errorMessage);
7729                 }
7730
7731                 if (requiredInstructionSet == null) {
7732                     requiredInstructionSet = instructionSet;
7733                     requirer = ps;
7734                 }
7735             }
7736         }
7737
7738         if (requiredInstructionSet != null) {
7739             String adjustedAbi;
7740             if (requirer != null) {
7741                 // requirer != null implies that either scannedPackage was null or that scannedPackage
7742                 // did not require an ABI, in which case we have to adjust scannedPackage to match
7743                 // the ABI of the set (which is the same as requirer's ABI)
7744                 adjustedAbi = requirer.primaryCpuAbiString;
7745                 if (scannedPackage != null) {
7746                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
7747                 }
7748             } else {
7749                 // requirer == null implies that we're updating all ABIs in the set to
7750                 // match scannedPackage.
7751                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
7752             }
7753
7754             for (PackageSetting ps : packagesForUser) {
7755                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
7756                     if (ps.primaryCpuAbiString != null) {
7757                         continue;
7758                     }
7759
7760                     ps.primaryCpuAbiString = adjustedAbi;
7761                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
7762                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
7763                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
7764
7765                         int result = mPackageDexOptimizer.performDexOpt(ps.pkg,
7766                                 null /* instruction sets */, forceDexOpt, deferDexOpt, true,
7767                                 bootComplete);
7768                         if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
7769                             ps.primaryCpuAbiString = null;
7770                             ps.pkg.applicationInfo.primaryCpuAbi = null;
7771                             return;
7772                         } else {
7773                             mInstaller.rmdex(ps.codePathString,
7774                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
7775                         }
7776                     }
7777                 }
7778             }
7779         }
7780     }
7781
7782     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
7783         synchronized (mPackages) {
7784             mResolverReplaced = true;
7785             // Set up information for custom user intent resolution activity.
7786             mResolveActivity.applicationInfo = pkg.applicationInfo;
7787             mResolveActivity.name = mCustomResolverComponentName.getClassName();
7788             mResolveActivity.packageName = pkg.applicationInfo.packageName;
7789             mResolveActivity.processName = pkg.applicationInfo.packageName;
7790             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
7791             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
7792                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
7793             mResolveActivity.theme = 0;
7794             mResolveActivity.exported = true;
7795             mResolveActivity.enabled = true;
7796             mResolveInfo.activityInfo = mResolveActivity;
7797             mResolveInfo.priority = 0;
7798             mResolveInfo.preferredOrder = 0;
7799             mResolveInfo.match = 0;
7800             mResolveComponentName = mCustomResolverComponentName;
7801             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
7802                     mResolveComponentName);
7803         }
7804     }
7805
7806     private static String calculateBundledApkRoot(final String codePathString) {
7807         final File codePath = new File(codePathString);
7808         final File codeRoot;
7809         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
7810             codeRoot = Environment.getRootDirectory();
7811         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
7812             codeRoot = Environment.getOemDirectory();
7813         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
7814             codeRoot = Environment.getVendorDirectory();
7815         } else {
7816             // Unrecognized code path; take its top real segment as the apk root:
7817             // e.g. /something/app/blah.apk => /something
7818             try {
7819                 File f = codePath.getCanonicalFile();
7820                 File parent = f.getParentFile();    // non-null because codePath is a file
7821                 File tmp;
7822                 while ((tmp = parent.getParentFile()) != null) {
7823                     f = parent;
7824                     parent = tmp;
7825                 }
7826                 codeRoot = f;
7827                 Slog.w(TAG, "Unrecognized code path "
7828                         + codePath + " - using " + codeRoot);
7829             } catch (IOException e) {
7830                 // Can't canonicalize the code path -- shenanigans?
7831                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
7832                 return Environment.getRootDirectory().getPath();
7833             }
7834         }
7835         return codeRoot.getPath();
7836     }
7837
7838     /**
7839      * Derive and set the location of native libraries for the given package,
7840      * which varies depending on where and how the package was installed.
7841      */
7842     private void setNativeLibraryPaths(PackageParser.Package pkg) {
7843         final ApplicationInfo info = pkg.applicationInfo;
7844         final String codePath = pkg.codePath;
7845         final File codeFile = new File(codePath);
7846         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
7847         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
7848
7849         info.nativeLibraryRootDir = null;
7850         info.nativeLibraryRootRequiresIsa = false;
7851         info.nativeLibraryDir = null;
7852         info.secondaryNativeLibraryDir = null;
7853
7854         if (isApkFile(codeFile)) {
7855             // Monolithic install
7856             if (bundledApp) {
7857                 // If "/system/lib64/apkname" exists, assume that is the per-package
7858                 // native library directory to use; otherwise use "/system/lib/apkname".
7859                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
7860                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
7861                         getPrimaryInstructionSet(info));
7862
7863                 // This is a bundled system app so choose the path based on the ABI.
7864                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
7865                 // is just the default path.
7866                 final String apkName = deriveCodePathName(codePath);
7867                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
7868                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
7869                         apkName).getAbsolutePath();
7870
7871                 if (info.secondaryCpuAbi != null) {
7872                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
7873                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
7874                             secondaryLibDir, apkName).getAbsolutePath();
7875                 }
7876             } else if (asecApp) {
7877                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
7878                         .getAbsolutePath();
7879             } else {
7880                 final String apkName = deriveCodePathName(codePath);
7881                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
7882                         .getAbsolutePath();
7883             }
7884
7885             info.nativeLibraryRootRequiresIsa = false;
7886             info.nativeLibraryDir = info.nativeLibraryRootDir;
7887         } else {
7888             // Cluster install
7889             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
7890             info.nativeLibraryRootRequiresIsa = true;
7891
7892             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
7893                     getPrimaryInstructionSet(info)).getAbsolutePath();
7894
7895             if (info.secondaryCpuAbi != null) {
7896                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
7897                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
7898             }
7899         }
7900     }
7901
7902     /**
7903      * Calculate the abis and roots for a bundled app. These can uniquely
7904      * be determined from the contents of the system partition, i.e whether
7905      * it contains 64 or 32 bit shared libraries etc. We do not validate any
7906      * of this information, and instead assume that the system was built
7907      * sensibly.
7908      */
7909     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
7910                                            PackageSetting pkgSetting) {
7911         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
7912
7913         // If "/system/lib64/apkname" exists, assume that is the per-package
7914         // native library directory to use; otherwise use "/system/lib/apkname".
7915         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
7916         setBundledAppAbi(pkg, apkRoot, apkName);
7917         // pkgSetting might be null during rescan following uninstall of updates
7918         // to a bundled app, so accommodate that possibility.  The settings in
7919         // that case will be established later from the parsed package.
7920         //
7921         // If the settings aren't null, sync them up with what we've just derived.
7922         // note that apkRoot isn't stored in the package settings.
7923         if (pkgSetting != null) {
7924             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7925             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7926         }
7927     }
7928
7929     /**
7930      * Deduces the ABI of a bundled app and sets the relevant fields on the
7931      * parsed pkg object.
7932      *
7933      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
7934      *        under which system libraries are installed.
7935      * @param apkName the name of the installed package.
7936      */
7937     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
7938         final File codeFile = new File(pkg.codePath);
7939
7940         final boolean has64BitLibs;
7941         final boolean has32BitLibs;
7942         if (isApkFile(codeFile)) {
7943             // Monolithic install
7944             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
7945             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
7946         } else {
7947             // Cluster install
7948             final File rootDir = new File(codeFile, LIB_DIR_NAME);
7949             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
7950                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
7951                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
7952                 has64BitLibs = (new File(rootDir, isa)).exists();
7953             } else {
7954                 has64BitLibs = false;
7955             }
7956             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
7957                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
7958                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
7959                 has32BitLibs = (new File(rootDir, isa)).exists();
7960             } else {
7961                 has32BitLibs = false;
7962             }
7963         }
7964
7965         if (has64BitLibs && !has32BitLibs) {
7966             // The package has 64 bit libs, but not 32 bit libs. Its primary
7967             // ABI should be 64 bit. We can safely assume here that the bundled
7968             // native libraries correspond to the most preferred ABI in the list.
7969
7970             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7971             pkg.applicationInfo.secondaryCpuAbi = null;
7972         } else if (has32BitLibs && !has64BitLibs) {
7973             // The package has 32 bit libs but not 64 bit libs. Its primary
7974             // ABI should be 32 bit.
7975
7976             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7977             pkg.applicationInfo.secondaryCpuAbi = null;
7978         } else if (has32BitLibs && has64BitLibs) {
7979             // The application has both 64 and 32 bit bundled libraries. We check
7980             // here that the app declares multiArch support, and warn if it doesn't.
7981             //
7982             // We will be lenient here and record both ABIs. The primary will be the
7983             // ABI that's higher on the list, i.e, a device that's configured to prefer
7984             // 64 bit apps will see a 64 bit primary ABI,
7985
7986             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
7987                 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
7988             }
7989
7990             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
7991                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7992                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7993             } else {
7994                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7995                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7996             }
7997         } else {
7998             pkg.applicationInfo.primaryCpuAbi = null;
7999             pkg.applicationInfo.secondaryCpuAbi = null;
8000         }
8001     }
8002
8003     private void killApplication(String pkgName, int appId, String reason) {
8004         // Request the ActivityManager to kill the process(only for existing packages)
8005         // so that we do not end up in a confused state while the user is still using the older
8006         // version of the application while the new one gets installed.
8007         IActivityManager am = ActivityManagerNative.getDefault();
8008         if (am != null) {
8009             try {
8010                 am.killApplicationWithAppId(pkgName, appId, reason);
8011             } catch (RemoteException e) {
8012             }
8013         }
8014     }
8015
8016     void removePackageLI(PackageSetting ps, boolean chatty) {
8017         if (DEBUG_INSTALL) {
8018             if (chatty)
8019                 Log.d(TAG, "Removing package " + ps.name);
8020         }
8021
8022         // writer
8023         synchronized (mPackages) {
8024             mPackages.remove(ps.name);
8025             final PackageParser.Package pkg = ps.pkg;
8026             if (pkg != null) {
8027                 cleanPackageDataStructuresLILPw(pkg, chatty);
8028             }
8029         }
8030     }
8031
8032     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
8033         if (DEBUG_INSTALL) {
8034             if (chatty)
8035                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
8036         }
8037
8038         // writer
8039         synchronized (mPackages) {
8040             mPackages.remove(pkg.applicationInfo.packageName);
8041             cleanPackageDataStructuresLILPw(pkg, chatty);
8042         }
8043     }
8044
8045     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
8046         int N = pkg.providers.size();
8047         StringBuilder r = null;
8048         int i;
8049         for (i=0; i<N; i++) {
8050             PackageParser.Provider p = pkg.providers.get(i);
8051             mProviders.removeProvider(p);
8052             if (p.info.authority == null) {
8053
8054                 /* There was another ContentProvider with this authority when
8055                  * this app was installed so this authority is null,
8056                  * Ignore it as we don't have to unregister the provider.
8057                  */
8058                 continue;
8059             }
8060             String names[] = p.info.authority.split(";");
8061             for (int j = 0; j < names.length; j++) {
8062                 if (mProvidersByAuthority.get(names[j]) == p) {
8063                     mProvidersByAuthority.remove(names[j]);
8064                     if (DEBUG_REMOVE) {
8065                         if (chatty)
8066                             Log.d(TAG, "Unregistered content provider: " + names[j]
8067                                     + ", className = " + p.info.name + ", isSyncable = "
8068                                     + p.info.isSyncable);
8069                     }
8070                 }
8071             }
8072             if (DEBUG_REMOVE && chatty) {
8073                 if (r == null) {
8074                     r = new StringBuilder(256);
8075                 } else {
8076                     r.append(' ');
8077                 }
8078                 r.append(p.info.name);
8079             }
8080         }
8081         if (r != null) {
8082             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
8083         }
8084
8085         N = pkg.services.size();
8086         r = null;
8087         for (i=0; i<N; i++) {
8088             PackageParser.Service s = pkg.services.get(i);
8089             mServices.removeService(s);
8090             if (chatty) {
8091                 if (r == null) {
8092                     r = new StringBuilder(256);
8093                 } else {
8094                     r.append(' ');
8095                 }
8096                 r.append(s.info.name);
8097             }
8098         }
8099         if (r != null) {
8100             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
8101         }
8102
8103         N = pkg.receivers.size();
8104         r = null;
8105         for (i=0; i<N; i++) {
8106             PackageParser.Activity a = pkg.receivers.get(i);
8107             mReceivers.removeActivity(a, "receiver");
8108             if (DEBUG_REMOVE && chatty) {
8109                 if (r == null) {
8110                     r = new StringBuilder(256);
8111                 } else {
8112                     r.append(' ');
8113                 }
8114                 r.append(a.info.name);
8115             }
8116         }
8117         if (r != null) {
8118             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
8119         }
8120
8121         N = pkg.activities.size();
8122         r = null;
8123         for (i=0; i<N; i++) {
8124             PackageParser.Activity a = pkg.activities.get(i);
8125             mActivities.removeActivity(a, "activity");
8126             if (DEBUG_REMOVE && chatty) {
8127                 if (r == null) {
8128                     r = new StringBuilder(256);
8129                 } else {
8130                     r.append(' ');
8131                 }
8132                 r.append(a.info.name);
8133             }
8134         }
8135         if (r != null) {
8136             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
8137         }
8138
8139         N = pkg.permissions.size();
8140         r = null;
8141         for (i=0; i<N; i++) {
8142             PackageParser.Permission p = pkg.permissions.get(i);
8143             BasePermission bp = mSettings.mPermissions.get(p.info.name);
8144             if (bp == null) {
8145                 bp = mSettings.mPermissionTrees.get(p.info.name);
8146             }
8147             if (bp != null && bp.perm == p) {
8148                 bp.perm = null;
8149                 if (DEBUG_REMOVE && chatty) {
8150                     if (r == null) {
8151                         r = new StringBuilder(256);
8152                     } else {
8153                         r.append(' ');
8154                     }
8155                     r.append(p.info.name);
8156                 }
8157             }
8158             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8159                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
8160                 if (appOpPerms != null) {
8161                     appOpPerms.remove(pkg.packageName);
8162                 }
8163             }
8164         }
8165         if (r != null) {
8166             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8167         }
8168
8169         N = pkg.requestedPermissions.size();
8170         r = null;
8171         for (i=0; i<N; i++) {
8172             String perm = pkg.requestedPermissions.get(i);
8173             BasePermission bp = mSettings.mPermissions.get(perm);
8174             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8175                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
8176                 if (appOpPerms != null) {
8177                     appOpPerms.remove(pkg.packageName);
8178                     if (appOpPerms.isEmpty()) {
8179                         mAppOpPermissionPackages.remove(perm);
8180                     }
8181                 }
8182             }
8183         }
8184         if (r != null) {
8185             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8186         }
8187
8188         N = pkg.instrumentation.size();
8189         r = null;
8190         for (i=0; i<N; i++) {
8191             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8192             mInstrumentation.remove(a.getComponentName());
8193             if (DEBUG_REMOVE && chatty) {
8194                 if (r == null) {
8195                     r = new StringBuilder(256);
8196                 } else {
8197                     r.append(' ');
8198                 }
8199                 r.append(a.info.name);
8200             }
8201         }
8202         if (r != null) {
8203             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
8204         }
8205
8206         r = null;
8207         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8208             // Only system apps can hold shared libraries.
8209             if (pkg.libraryNames != null) {
8210                 for (i=0; i<pkg.libraryNames.size(); i++) {
8211                     String name = pkg.libraryNames.get(i);
8212                     SharedLibraryEntry cur = mSharedLibraries.get(name);
8213                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
8214                         mSharedLibraries.remove(name);
8215                         if (DEBUG_REMOVE && chatty) {
8216                             if (r == null) {
8217                                 r = new StringBuilder(256);
8218                             } else {
8219                                 r.append(' ');
8220                             }
8221                             r.append(name);
8222                         }
8223                     }
8224                 }
8225             }
8226         }
8227         if (r != null) {
8228             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
8229         }
8230     }
8231
8232     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
8233         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
8234             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
8235                 return true;
8236             }
8237         }
8238         return false;
8239     }
8240
8241     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
8242     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
8243     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
8244
8245     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
8246             int flags) {
8247         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
8248         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
8249     }
8250
8251     private void updatePermissionsLPw(String changingPkg,
8252             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
8253         // Make sure there are no dangling permission trees.
8254         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
8255         while (it.hasNext()) {
8256             final BasePermission bp = it.next();
8257             if (bp.packageSetting == null) {
8258                 // We may not yet have parsed the package, so just see if
8259                 // we still know about its settings.
8260                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8261             }
8262             if (bp.packageSetting == null) {
8263                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
8264                         + " from package " + bp.sourcePackage);
8265                 it.remove();
8266             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8267                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8268                     Slog.i(TAG, "Removing old permission tree: " + bp.name
8269                             + " from package " + bp.sourcePackage);
8270                     flags |= UPDATE_PERMISSIONS_ALL;
8271                     it.remove();
8272                 }
8273             }
8274         }
8275
8276         // Make sure all dynamic permissions have been assigned to a package,
8277         // and make sure there are no dangling permissions.
8278         it = mSettings.mPermissions.values().iterator();
8279         while (it.hasNext()) {
8280             final BasePermission bp = it.next();
8281             if (bp.type == BasePermission.TYPE_DYNAMIC) {
8282                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
8283                         + bp.name + " pkg=" + bp.sourcePackage
8284                         + " info=" + bp.pendingInfo);
8285                 if (bp.packageSetting == null && bp.pendingInfo != null) {
8286                     final BasePermission tree = findPermissionTreeLP(bp.name);
8287                     if (tree != null && tree.perm != null) {
8288                         bp.packageSetting = tree.packageSetting;
8289                         bp.perm = new PackageParser.Permission(tree.perm.owner,
8290                                 new PermissionInfo(bp.pendingInfo));
8291                         bp.perm.info.packageName = tree.perm.info.packageName;
8292                         bp.perm.info.name = bp.name;
8293                         bp.uid = tree.uid;
8294                     }
8295                 }
8296             }
8297             if (bp.packageSetting == null) {
8298                 // We may not yet have parsed the package, so just see if
8299                 // we still know about its settings.
8300                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8301             }
8302             if (bp.packageSetting == null) {
8303                 Slog.w(TAG, "Removing dangling permission: " + bp.name
8304                         + " from package " + bp.sourcePackage);
8305                 it.remove();
8306             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8307                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8308                     Slog.i(TAG, "Removing old permission: " + bp.name
8309                             + " from package " + bp.sourcePackage);
8310                     flags |= UPDATE_PERMISSIONS_ALL;
8311                     it.remove();
8312                 }
8313             }
8314         }
8315
8316         // Now update the permissions for all packages, in particular
8317         // replace the granted permissions of the system packages.
8318         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
8319             for (PackageParser.Package pkg : mPackages.values()) {
8320                 if (pkg != pkgInfo) {
8321                     // Only replace for packages on requested volume
8322                     final String volumeUuid = getVolumeUuidForPackage(pkg);
8323                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
8324                             && Objects.equals(replaceVolumeUuid, volumeUuid);
8325                     grantPermissionsLPw(pkg, replace, changingPkg);
8326                 }
8327             }
8328         }
8329
8330         if (pkgInfo != null) {
8331             // Only replace for packages on requested volume
8332             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
8333             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
8334                     && Objects.equals(replaceVolumeUuid, volumeUuid);
8335             grantPermissionsLPw(pkgInfo, replace, changingPkg);
8336         }
8337     }
8338
8339     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
8340             String packageOfInterest) {
8341         // IMPORTANT: There are two types of permissions: install and runtime.
8342         // Install time permissions are granted when the app is installed to
8343         // all device users and users added in the future. Runtime permissions
8344         // are granted at runtime explicitly to specific users. Normal and signature
8345         // protected permissions are install time permissions. Dangerous permissions
8346         // are install permissions if the app's target SDK is Lollipop MR1 or older,
8347         // otherwise they are runtime permissions. This function does not manage
8348         // runtime permissions except for the case an app targeting Lollipop MR1
8349         // being upgraded to target a newer SDK, in which case dangerous permissions
8350         // are transformed from install time to runtime ones.
8351
8352         final PackageSetting ps = (PackageSetting) pkg.mExtras;
8353         if (ps == null) {
8354             return;
8355         }
8356
8357         PermissionsState permissionsState = ps.getPermissionsState();
8358         PermissionsState origPermissions = permissionsState;
8359
8360         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
8361
8362         boolean runtimePermissionsRevoked = false;
8363         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
8364
8365         boolean changedInstallPermission = false;
8366
8367         if (replace) {
8368             ps.installPermissionsFixed = false;
8369             if (!ps.isSharedUser()) {
8370                 origPermissions = new PermissionsState(permissionsState);
8371                 permissionsState.reset();
8372             } else {
8373                 // We need to know only about runtime permission changes since the
8374                 // calling code always writes the install permissions state but
8375                 // the runtime ones are written only if changed. The only cases of
8376                 // changed runtime permissions here are promotion of an install to
8377                 // runtime and revocation of a runtime from a shared user.
8378                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
8379                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
8380                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
8381                     runtimePermissionsRevoked = true;
8382                 }
8383             }
8384         }
8385
8386         permissionsState.setGlobalGids(mGlobalGids);
8387
8388         final int N = pkg.requestedPermissions.size();
8389         for (int i=0; i<N; i++) {
8390             final String name = pkg.requestedPermissions.get(i);
8391             final BasePermission bp = mSettings.mPermissions.get(name);
8392
8393             if (DEBUG_INSTALL) {
8394                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
8395             }
8396
8397             if (bp == null || bp.packageSetting == null) {
8398                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8399                     Slog.w(TAG, "Unknown permission " + name
8400                             + " in package " + pkg.packageName);
8401                 }
8402                 continue;
8403             }
8404
8405             final String perm = bp.name;
8406             boolean allowedSig = false;
8407             int grant = GRANT_DENIED;
8408
8409             // Keep track of app op permissions.
8410             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8411                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
8412                 if (pkgs == null) {
8413                     pkgs = new ArraySet<>();
8414                     mAppOpPermissionPackages.put(bp.name, pkgs);
8415                 }
8416                 pkgs.add(pkg.packageName);
8417             }
8418
8419             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
8420             switch (level) {
8421                 case PermissionInfo.PROTECTION_NORMAL: {
8422                     // For all apps normal permissions are install time ones.
8423                     grant = GRANT_INSTALL;
8424                 } break;
8425
8426                 case PermissionInfo.PROTECTION_DANGEROUS: {
8427                     if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
8428                         // For legacy apps dangerous permissions are install time ones.
8429                         grant = GRANT_INSTALL_LEGACY;
8430                     } else if (origPermissions.hasInstallPermission(bp.name)) {
8431                         // For legacy apps that became modern, install becomes runtime.
8432                         grant = GRANT_UPGRADE;
8433                     } else if (mPromoteSystemApps
8434                             && isSystemApp(ps)
8435                             && mExistingSystemPackages.contains(ps.name)) {
8436                         // For legacy system apps, install becomes runtime.
8437                         // We cannot check hasInstallPermission() for system apps since those
8438                         // permissions were granted implicitly and not persisted pre-M.
8439                         grant = GRANT_UPGRADE;
8440                     } else {
8441                         // For modern apps keep runtime permissions unchanged.
8442                         grant = GRANT_RUNTIME;
8443                     }
8444                 } break;
8445
8446                 case PermissionInfo.PROTECTION_SIGNATURE: {
8447                     // For all apps signature permissions are install time ones.
8448                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
8449                     if (allowedSig) {
8450                         grant = GRANT_INSTALL;
8451                     }
8452                 } break;
8453             }
8454
8455             if (DEBUG_INSTALL) {
8456                 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
8457             }
8458
8459             if (grant != GRANT_DENIED) {
8460                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
8461                     // If this is an existing, non-system package, then
8462                     // we can't add any new permissions to it.
8463                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
8464                         // Except...  if this is a permission that was added
8465                         // to the platform (note: need to only do this when
8466                         // updating the platform).
8467                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
8468                             grant = GRANT_DENIED;
8469                         }
8470                     }
8471                 }
8472
8473                 switch (grant) {
8474                     case GRANT_INSTALL: {
8475                         // Revoke this as runtime permission to handle the case of
8476                         // a runtime permission being downgraded to an install one.
8477                         for (int userId : UserManagerService.getInstance().getUserIds()) {
8478                             if (origPermissions.getRuntimePermissionState(
8479                                     bp.name, userId) != null) {
8480                                 // Revoke the runtime permission and clear the flags.
8481                                 origPermissions.revokeRuntimePermission(bp, userId);
8482                                 origPermissions.updatePermissionFlags(bp, userId,
8483                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
8484                                 // If we revoked a permission permission, we have to write.
8485                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8486                                         changedRuntimePermissionUserIds, userId);
8487                             }
8488                         }
8489                         // Grant an install permission.
8490                         if (permissionsState.grantInstallPermission(bp) !=
8491                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
8492                             changedInstallPermission = true;
8493                         }
8494                     } break;
8495
8496                     case GRANT_INSTALL_LEGACY: {
8497                         // Grant an install permission.
8498                         if (permissionsState.grantInstallPermission(bp) !=
8499                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
8500                             changedInstallPermission = true;
8501                         }
8502                     } break;
8503
8504                     case GRANT_RUNTIME: {
8505                         // Grant previously granted runtime permissions.
8506                         for (int userId : UserManagerService.getInstance().getUserIds()) {
8507                             PermissionState permissionState = origPermissions
8508                                     .getRuntimePermissionState(bp.name, userId);
8509                             final int flags = permissionState != null
8510                                     ? permissionState.getFlags() : 0;
8511                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
8512                                 if (permissionsState.grantRuntimePermission(bp, userId) ==
8513                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
8514                                     // If we cannot put the permission as it was, we have to write.
8515                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8516                                             changedRuntimePermissionUserIds, userId);
8517                                 }
8518                             }
8519                             // Propagate the permission flags.
8520                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
8521                         }
8522                     } break;
8523
8524                     case GRANT_UPGRADE: {
8525                         // Grant runtime permissions for a previously held install permission.
8526                         PermissionState permissionState = origPermissions
8527                                 .getInstallPermissionState(bp.name);
8528                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
8529
8530                         if (origPermissions.revokeInstallPermission(bp)
8531                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
8532                             // We will be transferring the permission flags, so clear them.
8533                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
8534                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
8535                             changedInstallPermission = true;
8536                         }
8537
8538                         // If the permission is not to be promoted to runtime we ignore it and
8539                         // also its other flags as they are not applicable to install permissions.
8540                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
8541                             for (int userId : currentUserIds) {
8542                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
8543                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
8544                                     // Transfer the permission flags.
8545                                     permissionsState.updatePermissionFlags(bp, userId,
8546                                             flags, flags);
8547                                     // If we granted the permission, we have to write.
8548                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8549                                             changedRuntimePermissionUserIds, userId);
8550                                 }
8551                             }
8552                         }
8553                     } break;
8554
8555                     default: {
8556                         if (packageOfInterest == null
8557                                 || packageOfInterest.equals(pkg.packageName)) {
8558                             Slog.w(TAG, "Not granting permission " + perm
8559                                     + " to package " + pkg.packageName
8560                                     + " because it was previously installed without");
8561                         }
8562                     } break;
8563                 }
8564             } else {
8565                 if (permissionsState.revokeInstallPermission(bp) !=
8566                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
8567                     // Also drop the permission flags.
8568                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
8569                             PackageManager.MASK_PERMISSION_FLAGS, 0);
8570                     changedInstallPermission = true;
8571                     Slog.i(TAG, "Un-granting permission " + perm
8572                             + " from package " + pkg.packageName
8573                             + " (protectionLevel=" + bp.protectionLevel
8574                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8575                             + ")");
8576                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
8577                     // Don't print warning for app op permissions, since it is fine for them
8578                     // not to be granted, there is a UI for the user to decide.
8579                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8580                         Slog.w(TAG, "Not granting permission " + perm
8581                                 + " to package " + pkg.packageName
8582                                 + " (protectionLevel=" + bp.protectionLevel
8583                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8584                                 + ")");
8585                     }
8586                 }
8587             }
8588         }
8589
8590         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
8591                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
8592             // This is the first that we have heard about this package, so the
8593             // permissions we have now selected are fixed until explicitly
8594             // changed.
8595             ps.installPermissionsFixed = true;
8596         }
8597
8598         // Persist the runtime permissions state for users with changes. If permissions
8599         // were revoked because no app in the shared user declares them we have to
8600         // write synchronously to avoid losing runtime permissions state.
8601         for (int userId : changedRuntimePermissionUserIds) {
8602             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
8603         }
8604     }
8605
8606     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
8607         boolean allowed = false;
8608         final int NP = PackageParser.NEW_PERMISSIONS.length;
8609         for (int ip=0; ip<NP; ip++) {
8610             final PackageParser.NewPermissionInfo npi
8611                     = PackageParser.NEW_PERMISSIONS[ip];
8612             if (npi.name.equals(perm)
8613                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
8614                 allowed = true;
8615                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
8616                         + pkg.packageName);
8617                 break;
8618             }
8619         }
8620         return allowed;
8621     }
8622
8623     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
8624             BasePermission bp, PermissionsState origPermissions) {
8625         boolean allowed;
8626         allowed = (compareSignatures(
8627                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
8628                         == PackageManager.SIGNATURE_MATCH)
8629                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
8630                         == PackageManager.SIGNATURE_MATCH);
8631         if (!allowed && (bp.protectionLevel
8632                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
8633             if (isSystemApp(pkg)) {
8634                 // For updated system applications, a system permission
8635                 // is granted only if it had been defined by the original application.
8636                 if (pkg.isUpdatedSystemApp()) {
8637                     final PackageSetting sysPs = mSettings
8638                             .getDisabledSystemPkgLPr(pkg.packageName);
8639                     if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
8640                         // If the original was granted this permission, we take
8641                         // that grant decision as read and propagate it to the
8642                         // update.
8643                         if (sysPs.isPrivileged()) {
8644                             allowed = true;
8645                         }
8646                     } else {
8647                         // The system apk may have been updated with an older
8648                         // version of the one on the data partition, but which
8649                         // granted a new system permission that it didn't have
8650                         // before.  In this case we do want to allow the app to
8651                         // now get the new permission if the ancestral apk is
8652                         // privileged to get it.
8653                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
8654                             for (int j=0;
8655                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
8656                                 if (perm.equals(
8657                                         sysPs.pkg.requestedPermissions.get(j))) {
8658                                     allowed = true;
8659                                     break;
8660                                 }
8661                             }
8662                         }
8663                     }
8664                 } else {
8665                     allowed = isPrivilegedApp(pkg);
8666                 }
8667             }
8668         }
8669         if (!allowed) {
8670             if (!allowed && (bp.protectionLevel
8671                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
8672                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
8673                 // If this was a previously normal/dangerous permission that got moved
8674                 // to a system permission as part of the runtime permission redesign, then
8675                 // we still want to blindly grant it to old apps.
8676                 allowed = true;
8677             }
8678             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
8679                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
8680                 // If this permission is to be granted to the system installer and
8681                 // this app is an installer, then it gets the permission.
8682                 allowed = true;
8683             }
8684             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
8685                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
8686                 // If this permission is to be granted to the system verifier and
8687                 // this app is a verifier, then it gets the permission.
8688                 allowed = true;
8689             }
8690             if (!allowed && (bp.protectionLevel
8691                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
8692                     && isSystemApp(pkg)) {
8693                 // Any pre-installed system app is allowed to get this permission.
8694                 allowed = true;
8695             }
8696             if (!allowed && (bp.protectionLevel
8697                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
8698                 // For development permissions, a development permission
8699                 // is granted only if it was already granted.
8700                 allowed = origPermissions.hasInstallPermission(perm);
8701             }
8702         }
8703         return allowed;
8704     }
8705
8706     final class ActivityIntentResolver
8707             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
8708         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
8709                 boolean defaultOnly, int userId) {
8710             if (!sUserManager.exists(userId)) return null;
8711             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
8712             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
8713         }
8714
8715         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
8716                 int userId) {
8717             if (!sUserManager.exists(userId)) return null;
8718             mFlags = flags;
8719             return super.queryIntent(intent, resolvedType,
8720                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
8721         }
8722
8723         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
8724                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
8725             if (!sUserManager.exists(userId)) return null;
8726             if (packageActivities == null) {
8727                 return null;
8728             }
8729             mFlags = flags;
8730             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
8731             final int N = packageActivities.size();
8732             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
8733                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
8734
8735             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
8736             for (int i = 0; i < N; ++i) {
8737                 intentFilters = packageActivities.get(i).intents;
8738                 if (intentFilters != null && intentFilters.size() > 0) {
8739                     PackageParser.ActivityIntentInfo[] array =
8740                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
8741                     intentFilters.toArray(array);
8742                     listCut.add(array);
8743                 }
8744             }
8745             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
8746         }
8747
8748         /**
8749          * Finds a privileged activity that matches the specified activity names.
8750          */
8751         private PackageParser.Activity findMatchingActivity(
8752                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
8753             for (PackageParser.Activity sysActivity : activityList) {
8754                 if (sysActivity.info.name.equals(activityInfo.name)) {
8755                     return sysActivity;
8756                 }
8757                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
8758                     return sysActivity;
8759                 }
8760                 if (sysActivity.info.targetActivity != null) {
8761                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
8762                         return sysActivity;
8763                     }
8764                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
8765                         return sysActivity;
8766                     }
8767                 }
8768             }
8769             return null;
8770         }
8771
8772         public class IterGenerator<E> {
8773             public Iterator<E> generate(ActivityIntentInfo info) {
8774                 return null;
8775             }
8776         }
8777
8778         public class ActionIterGenerator extends IterGenerator<String> {
8779             @Override
8780             public Iterator<String> generate(ActivityIntentInfo info) {
8781                 return info.actionsIterator();
8782             }
8783         }
8784
8785         public class CategoriesIterGenerator extends IterGenerator<String> {
8786             @Override
8787             public Iterator<String> generate(ActivityIntentInfo info) {
8788                 return info.categoriesIterator();
8789             }
8790         }
8791
8792         public class SchemesIterGenerator extends IterGenerator<String> {
8793             @Override
8794             public Iterator<String> generate(ActivityIntentInfo info) {
8795                 return info.schemesIterator();
8796             }
8797         }
8798
8799         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
8800             @Override
8801             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
8802                 return info.authoritiesIterator();
8803             }
8804         }
8805
8806         /**
8807          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
8808          * MODIFIED. Do not pass in a list that should not be changed.
8809          */
8810         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
8811                 IterGenerator<T> generator, Iterator<T> searchIterator) {
8812             // loop through the set of actions; every one must be found in the intent filter
8813             while (searchIterator.hasNext()) {
8814                 // we must have at least one filter in the list to consider a match
8815                 if (intentList.size() == 0) {
8816                     break;
8817                 }
8818
8819                 final T searchAction = searchIterator.next();
8820
8821                 // loop through the set of intent filters
8822                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
8823                 while (intentIter.hasNext()) {
8824                     final ActivityIntentInfo intentInfo = intentIter.next();
8825                     boolean selectionFound = false;
8826
8827                     // loop through the intent filter's selection criteria; at least one
8828                     // of them must match the searched criteria
8829                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
8830                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
8831                         final T intentSelection = intentSelectionIter.next();
8832                         if (intentSelection != null && intentSelection.equals(searchAction)) {
8833                             selectionFound = true;
8834                             break;
8835                         }
8836                     }
8837
8838                     // the selection criteria wasn't found in this filter's set; this filter
8839                     // is not a potential match
8840                     if (!selectionFound) {
8841                         intentIter.remove();
8842                     }
8843                 }
8844             }
8845         }
8846
8847         /**
8848          * Adjusts the priority of the given intent filter according to policy.
8849          * <p>
8850          * <ul>
8851          * <li>The priority for unbundled updates to system applications is capped to the
8852          *      priority defined on the system partition</li>
8853          * </ul>
8854          */
8855         private void adjustPriority(
8856                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
8857             // nothing to do; priority is fine as-is
8858             if (intent.getPriority() <= 0) {
8859                 return;
8860             }
8861
8862             final ActivityInfo activityInfo = intent.activity.info;
8863             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
8864
8865             final boolean systemApp = applicationInfo.isSystemApp();
8866             if (!systemApp) {
8867                 // non-system applications can never define a priority >0
8868                 Slog.w(TAG, "Non-system app; cap priority to 0;"
8869                         + " package: " + applicationInfo.packageName
8870                         + " activity: " + intent.activity.className
8871                         + " origPrio: " + intent.getPriority());
8872                 intent.setPriority(0);
8873                 return;
8874             }
8875
8876             if (systemActivities == null) {
8877                 // the system package is not disabled; we're parsing the system partition
8878                 // apps on the system image get whatever priority they request
8879                 return;
8880             }
8881
8882             // system app unbundled update ... try to find the same activity
8883             final PackageParser.Activity foundActivity =
8884                     findMatchingActivity(systemActivities, activityInfo);
8885             if (foundActivity == null) {
8886                 // this is a new activity; it cannot obtain >0 priority
8887                 if (DEBUG_FILTERS) {
8888                     Slog.i(TAG, "New activity; cap priority to 0;"
8889                             + " package: " + applicationInfo.packageName
8890                             + " activity: " + intent.activity.className
8891                             + " origPrio: " + intent.getPriority());
8892                 }
8893                 intent.setPriority(0);
8894                 return;
8895             }
8896
8897             // found activity, now check for filter equivalence
8898
8899             // a shallow copy is enough; we modify the list, not its contents
8900             final List<ActivityIntentInfo> intentListCopy =
8901                     new ArrayList<>(foundActivity.intents);
8902             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
8903
8904             // find matching action subsets
8905             final Iterator<String> actionsIterator = intent.actionsIterator();
8906             if (actionsIterator != null) {
8907                 getIntentListSubset(
8908                         intentListCopy, new ActionIterGenerator(), actionsIterator);
8909                 if (intentListCopy.size() == 0) {
8910                     // no more intents to match; we're not equivalent
8911                     if (DEBUG_FILTERS) {
8912                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
8913                                 + " package: " + applicationInfo.packageName
8914                                 + " activity: " + intent.activity.className
8915                                 + " origPrio: " + intent.getPriority());
8916                     }
8917                     intent.setPriority(0);
8918                     return;
8919                 }
8920             }
8921
8922             // find matching category subsets
8923             final Iterator<String> categoriesIterator = intent.categoriesIterator();
8924             if (categoriesIterator != null) {
8925                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
8926                         categoriesIterator);
8927                 if (intentListCopy.size() == 0) {
8928                     // no more intents to match; we're not equivalent
8929                     if (DEBUG_FILTERS) {
8930                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
8931                                 + " package: " + applicationInfo.packageName
8932                                 + " activity: " + intent.activity.className
8933                                 + " origPrio: " + intent.getPriority());
8934                     }
8935                     intent.setPriority(0);
8936                     return;
8937                 }
8938             }
8939
8940             // find matching schemes subsets
8941             final Iterator<String> schemesIterator = intent.schemesIterator();
8942             if (schemesIterator != null) {
8943                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
8944                         schemesIterator);
8945                 if (intentListCopy.size() == 0) {
8946                     // no more intents to match; we're not equivalent
8947                     if (DEBUG_FILTERS) {
8948                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
8949                                 + " package: " + applicationInfo.packageName
8950                                 + " activity: " + intent.activity.className
8951                                 + " origPrio: " + intent.getPriority());
8952                     }
8953                     intent.setPriority(0);
8954                     return;
8955                 }
8956             }
8957
8958             // find matching authorities subsets
8959             final Iterator<IntentFilter.AuthorityEntry>
8960                     authoritiesIterator = intent.authoritiesIterator();
8961             if (authoritiesIterator != null) {
8962                 getIntentListSubset(intentListCopy,
8963                         new AuthoritiesIterGenerator(),
8964                         authoritiesIterator);
8965                 if (intentListCopy.size() == 0) {
8966                     // no more intents to match; we're not equivalent
8967                     if (DEBUG_FILTERS) {
8968                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
8969                                 + " package: " + applicationInfo.packageName
8970                                 + " activity: " + intent.activity.className
8971                                 + " origPrio: " + intent.getPriority());
8972                     }
8973                     intent.setPriority(0);
8974                     return;
8975                 }
8976             }
8977
8978             // we found matching filter(s); app gets the max priority of all intents
8979             int cappedPriority = 0;
8980             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
8981                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
8982             }
8983             if (intent.getPriority() > cappedPriority) {
8984                 if (DEBUG_FILTERS) {
8985                     Slog.i(TAG, "Found matching filter(s);"
8986                             + " cap priority to " + cappedPriority + ";"
8987                             + " package: " + applicationInfo.packageName
8988                             + " activity: " + intent.activity.className
8989                             + " origPrio: " + intent.getPriority());
8990                 }
8991                 intent.setPriority(cappedPriority);
8992                 return;
8993             }
8994             // all this for nothing; the requested priority was <= what was on the system
8995         }
8996
8997         public final void addActivity(PackageParser.Activity a, String type) {
8998             final boolean systemApp = a.info.applicationInfo.isSystemApp();
8999             mActivities.put(a.getComponentName(), a);
9000             if (DEBUG_SHOW_INFO)
9001                 Log.v(
9002                 TAG, "  " + type + " " +
9003                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
9004             if (DEBUG_SHOW_INFO)
9005                 Log.v(TAG, "    Class=" + a.info.name);
9006             final int NI = a.intents.size();
9007             for (int j=0; j<NI; j++) {
9008                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9009                 if ("activity".equals(type)) {
9010                     final PackageSetting ps =
9011                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
9012                     final List<PackageParser.Activity> systemActivities =
9013                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
9014                     adjustPriority(systemActivities, intent);
9015                 }
9016                 if (DEBUG_SHOW_INFO) {
9017                     Log.v(TAG, "    IntentFilter:");
9018                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9019                 }
9020                 if (!intent.debugCheck()) {
9021                     Log.w(TAG, "==> For Activity " + a.info.name);
9022                 }
9023                 addFilter(intent);
9024             }
9025         }
9026
9027         public final void removeActivity(PackageParser.Activity a, String type) {
9028             mActivities.remove(a.getComponentName());
9029             if (DEBUG_SHOW_INFO) {
9030                 Log.v(TAG, "  " + type + " "
9031                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
9032                                 : a.info.name) + ":");
9033                 Log.v(TAG, "    Class=" + a.info.name);
9034             }
9035             final int NI = a.intents.size();
9036             for (int j=0; j<NI; j++) {
9037                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9038                 if (DEBUG_SHOW_INFO) {
9039                     Log.v(TAG, "    IntentFilter:");
9040                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9041                 }
9042                 removeFilter(intent);
9043             }
9044         }
9045
9046         @Override
9047         protected boolean allowFilterResult(
9048                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
9049             ActivityInfo filterAi = filter.activity.info;
9050             for (int i=dest.size()-1; i>=0; i--) {
9051                 ActivityInfo destAi = dest.get(i).activityInfo;
9052                 if (destAi.name == filterAi.name
9053                         && destAi.packageName == filterAi.packageName) {
9054                     return false;
9055                 }
9056             }
9057             return true;
9058         }
9059
9060         @Override
9061         protected ActivityIntentInfo[] newArray(int size) {
9062             return new ActivityIntentInfo[size];
9063         }
9064
9065         @Override
9066         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
9067             if (!sUserManager.exists(userId)) return true;
9068             PackageParser.Package p = filter.activity.owner;
9069             if (p != null) {
9070                 PackageSetting ps = (PackageSetting)p.mExtras;
9071                 if (ps != null) {
9072                     // System apps are never considered stopped for purposes of
9073                     // filtering, because there may be no way for the user to
9074                     // actually re-launch them.
9075                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
9076                             && ps.getStopped(userId);
9077                 }
9078             }
9079             return false;
9080         }
9081
9082         @Override
9083         protected boolean isPackageForFilter(String packageName,
9084                 PackageParser.ActivityIntentInfo info) {
9085             return packageName.equals(info.activity.owner.packageName);
9086         }
9087
9088         @Override
9089         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
9090                 int match, int userId) {
9091             if (!sUserManager.exists(userId)) return null;
9092             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
9093                 return null;
9094             }
9095             final PackageParser.Activity activity = info.activity;
9096             if (mSafeMode && (activity.info.applicationInfo.flags
9097                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
9098                 return null;
9099             }
9100             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
9101             if (ps == null) {
9102                 return null;
9103             }
9104             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
9105                     ps.readUserState(userId), userId);
9106             if (ai == null) {
9107                 return null;
9108             }
9109             final ResolveInfo res = new ResolveInfo();
9110             res.activityInfo = ai;
9111             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9112                 res.filter = info;
9113             }
9114             if (info != null) {
9115                 res.handleAllWebDataURI = info.handleAllWebDataURI();
9116             }
9117             res.priority = info.getPriority();
9118             res.preferredOrder = activity.owner.mPreferredOrder;
9119             //System.out.println("Result: " + res.activityInfo.className +
9120             //                   " = " + res.priority);
9121             res.match = match;
9122             res.isDefault = info.hasDefault;
9123             res.labelRes = info.labelRes;
9124             res.nonLocalizedLabel = info.nonLocalizedLabel;
9125             if (userNeedsBadging(userId)) {
9126                 res.noResourceId = true;
9127             } else {
9128                 res.icon = info.icon;
9129             }
9130             res.iconResourceId = info.icon;
9131             res.system = res.activityInfo.applicationInfo.isSystemApp();
9132             return res;
9133         }
9134
9135         @Override
9136         protected void sortResults(List<ResolveInfo> results) {
9137             Collections.sort(results, mResolvePrioritySorter);
9138         }
9139
9140         @Override
9141         protected void dumpFilter(PrintWriter out, String prefix,
9142                 PackageParser.ActivityIntentInfo filter) {
9143             out.print(prefix); out.print(
9144                     Integer.toHexString(System.identityHashCode(filter.activity)));
9145                     out.print(' ');
9146                     filter.activity.printComponentShortName(out);
9147                     out.print(" filter ");
9148                     out.println(Integer.toHexString(System.identityHashCode(filter)));
9149         }
9150
9151         @Override
9152         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
9153             return filter.activity;
9154         }
9155
9156         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9157             PackageParser.Activity activity = (PackageParser.Activity)label;
9158             out.print(prefix); out.print(
9159                     Integer.toHexString(System.identityHashCode(activity)));
9160                     out.print(' ');
9161                     activity.printComponentShortName(out);
9162             if (count > 1) {
9163                 out.print(" ("); out.print(count); out.print(" filters)");
9164             }
9165             out.println();
9166         }
9167
9168         // Keys are String (activity class name), values are Activity.
9169         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
9170                 = new ArrayMap<ComponentName, PackageParser.Activity>();
9171         private int mFlags;
9172     }
9173
9174     private final class ServiceIntentResolver
9175             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
9176         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9177                 boolean defaultOnly, int userId) {
9178             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9179             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9180         }
9181
9182         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9183                 int userId) {
9184             if (!sUserManager.exists(userId)) return null;
9185             mFlags = flags;
9186             return super.queryIntent(intent, resolvedType,
9187                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9188         }
9189
9190         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9191                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
9192             if (!sUserManager.exists(userId)) return null;
9193             if (packageServices == null) {
9194                 return null;
9195             }
9196             mFlags = flags;
9197             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9198             final int N = packageServices.size();
9199             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
9200                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
9201
9202             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
9203             for (int i = 0; i < N; ++i) {
9204                 intentFilters = packageServices.get(i).intents;
9205                 if (intentFilters != null && intentFilters.size() > 0) {
9206                     PackageParser.ServiceIntentInfo[] array =
9207                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
9208                     intentFilters.toArray(array);
9209                     listCut.add(array);
9210                 }
9211             }
9212             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9213         }
9214
9215         public final void addService(PackageParser.Service s) {
9216             mServices.put(s.getComponentName(), s);
9217             if (DEBUG_SHOW_INFO) {
9218                 Log.v(TAG, "  "
9219                         + (s.info.nonLocalizedLabel != null
9220                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
9221                 Log.v(TAG, "    Class=" + s.info.name);
9222             }
9223             final int NI = s.intents.size();
9224             int j;
9225             for (j=0; j<NI; j++) {
9226                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9227                 if (DEBUG_SHOW_INFO) {
9228                     Log.v(TAG, "    IntentFilter:");
9229                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9230                 }
9231                 if (!intent.debugCheck()) {
9232                     Log.w(TAG, "==> For Service " + s.info.name);
9233                 }
9234                 addFilter(intent);
9235             }
9236         }
9237
9238         public final void removeService(PackageParser.Service s) {
9239             mServices.remove(s.getComponentName());
9240             if (DEBUG_SHOW_INFO) {
9241                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
9242                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
9243                 Log.v(TAG, "    Class=" + s.info.name);
9244             }
9245             final int NI = s.intents.size();
9246             int j;
9247             for (j=0; j<NI; j++) {
9248                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9249                 if (DEBUG_SHOW_INFO) {
9250                     Log.v(TAG, "    IntentFilter:");
9251                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9252                 }
9253                 removeFilter(intent);
9254             }
9255         }
9256
9257         @Override
9258         protected boolean allowFilterResult(
9259                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
9260             ServiceInfo filterSi = filter.service.info;
9261             for (int i=dest.size()-1; i>=0; i--) {
9262                 ServiceInfo destAi = dest.get(i).serviceInfo;
9263                 if (destAi.name == filterSi.name
9264                         && destAi.packageName == filterSi.packageName) {
9265                     return false;
9266                 }
9267             }
9268             return true;
9269         }
9270
9271         @Override
9272         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
9273             return new PackageParser.ServiceIntentInfo[size];
9274         }
9275
9276         @Override
9277         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
9278             if (!sUserManager.exists(userId)) return true;
9279             PackageParser.Package p = filter.service.owner;
9280             if (p != null) {
9281                 PackageSetting ps = (PackageSetting)p.mExtras;
9282                 if (ps != null) {
9283                     // System apps are never considered stopped for purposes of
9284                     // filtering, because there may be no way for the user to
9285                     // actually re-launch them.
9286                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9287                             && ps.getStopped(userId);
9288                 }
9289             }
9290             return false;
9291         }
9292
9293         @Override
9294         protected boolean isPackageForFilter(String packageName,
9295                 PackageParser.ServiceIntentInfo info) {
9296             return packageName.equals(info.service.owner.packageName);
9297         }
9298
9299         @Override
9300         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
9301                 int match, int userId) {
9302             if (!sUserManager.exists(userId)) return null;
9303             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
9304             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
9305                 return null;
9306             }
9307             final PackageParser.Service service = info.service;
9308             if (mSafeMode && (service.info.applicationInfo.flags
9309                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
9310                 return null;
9311             }
9312             PackageSetting ps = (PackageSetting) service.owner.mExtras;
9313             if (ps == null) {
9314                 return null;
9315             }
9316             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
9317                     ps.readUserState(userId), userId);
9318             if (si == null) {
9319                 return null;
9320             }
9321             final ResolveInfo res = new ResolveInfo();
9322             res.serviceInfo = si;
9323             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9324                 res.filter = filter;
9325             }
9326             res.priority = info.getPriority();
9327             res.preferredOrder = service.owner.mPreferredOrder;
9328             res.match = match;
9329             res.isDefault = info.hasDefault;
9330             res.labelRes = info.labelRes;
9331             res.nonLocalizedLabel = info.nonLocalizedLabel;
9332             res.icon = info.icon;
9333             res.system = res.serviceInfo.applicationInfo.isSystemApp();
9334             return res;
9335         }
9336
9337         @Override
9338         protected void sortResults(List<ResolveInfo> results) {
9339             Collections.sort(results, mResolvePrioritySorter);
9340         }
9341
9342         @Override
9343         protected void dumpFilter(PrintWriter out, String prefix,
9344                 PackageParser.ServiceIntentInfo filter) {
9345             out.print(prefix); out.print(
9346                     Integer.toHexString(System.identityHashCode(filter.service)));
9347                     out.print(' ');
9348                     filter.service.printComponentShortName(out);
9349                     out.print(" filter ");
9350                     out.println(Integer.toHexString(System.identityHashCode(filter)));
9351         }
9352
9353         @Override
9354         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
9355             return filter.service;
9356         }
9357
9358         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9359             PackageParser.Service service = (PackageParser.Service)label;
9360             out.print(prefix); out.print(
9361                     Integer.toHexString(System.identityHashCode(service)));
9362                     out.print(' ');
9363                     service.printComponentShortName(out);
9364             if (count > 1) {
9365                 out.print(" ("); out.print(count); out.print(" filters)");
9366             }
9367             out.println();
9368         }
9369
9370 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9371 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9372 //            final List<ResolveInfo> retList = Lists.newArrayList();
9373 //            while (i.hasNext()) {
9374 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
9375 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
9376 //                    retList.add(resolveInfo);
9377 //                }
9378 //            }
9379 //            return retList;
9380 //        }
9381
9382         // Keys are String (activity class name), values are Activity.
9383         private final ArrayMap<ComponentName, PackageParser.Service> mServices
9384                 = new ArrayMap<ComponentName, PackageParser.Service>();
9385         private int mFlags;
9386     };
9387
9388     private final class ProviderIntentResolver
9389             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
9390         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9391                 boolean defaultOnly, int userId) {
9392             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9393             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9394         }
9395
9396         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9397                 int userId) {
9398             if (!sUserManager.exists(userId))
9399                 return null;
9400             mFlags = flags;
9401             return super.queryIntent(intent, resolvedType,
9402                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9403         }
9404
9405         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9406                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
9407             if (!sUserManager.exists(userId))
9408                 return null;
9409             if (packageProviders == null) {
9410                 return null;
9411             }
9412             mFlags = flags;
9413             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
9414             final int N = packageProviders.size();
9415             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
9416                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
9417
9418             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
9419             for (int i = 0; i < N; ++i) {
9420                 intentFilters = packageProviders.get(i).intents;
9421                 if (intentFilters != null && intentFilters.size() > 0) {
9422                     PackageParser.ProviderIntentInfo[] array =
9423                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
9424                     intentFilters.toArray(array);
9425                     listCut.add(array);
9426                 }
9427             }
9428             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9429         }
9430
9431         public final void addProvider(PackageParser.Provider p) {
9432             if (mProviders.containsKey(p.getComponentName())) {
9433                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
9434                 return;
9435             }
9436
9437             mProviders.put(p.getComponentName(), p);
9438             if (DEBUG_SHOW_INFO) {
9439                 Log.v(TAG, "  "
9440                         + (p.info.nonLocalizedLabel != null
9441                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
9442                 Log.v(TAG, "    Class=" + p.info.name);
9443             }
9444             final int NI = p.intents.size();
9445             int j;
9446             for (j = 0; j < NI; j++) {
9447                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9448                 if (DEBUG_SHOW_INFO) {
9449                     Log.v(TAG, "    IntentFilter:");
9450                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9451                 }
9452                 if (!intent.debugCheck()) {
9453                     Log.w(TAG, "==> For Provider " + p.info.name);
9454                 }
9455                 addFilter(intent);
9456             }
9457         }
9458
9459         public final void removeProvider(PackageParser.Provider p) {
9460             mProviders.remove(p.getComponentName());
9461             if (DEBUG_SHOW_INFO) {
9462                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
9463                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
9464                 Log.v(TAG, "    Class=" + p.info.name);
9465             }
9466             final int NI = p.intents.size();
9467             int j;
9468             for (j = 0; j < NI; j++) {
9469                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9470                 if (DEBUG_SHOW_INFO) {
9471                     Log.v(TAG, "    IntentFilter:");
9472                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9473                 }
9474                 removeFilter(intent);
9475             }
9476         }
9477
9478         @Override
9479         protected boolean allowFilterResult(
9480                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
9481             ProviderInfo filterPi = filter.provider.info;
9482             for (int i = dest.size() - 1; i >= 0; i--) {
9483                 ProviderInfo destPi = dest.get(i).providerInfo;
9484                 if (destPi.name == filterPi.name
9485                         && destPi.packageName == filterPi.packageName) {
9486                     return false;
9487                 }
9488             }
9489             return true;
9490         }
9491
9492         @Override
9493         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
9494             return new PackageParser.ProviderIntentInfo[size];
9495         }
9496
9497         @Override
9498         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
9499             if (!sUserManager.exists(userId))
9500                 return true;
9501             PackageParser.Package p = filter.provider.owner;
9502             if (p != null) {
9503                 PackageSetting ps = (PackageSetting) p.mExtras;
9504                 if (ps != null) {
9505                     // System apps are never considered stopped for purposes of
9506                     // filtering, because there may be no way for the user to
9507                     // actually re-launch them.
9508                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9509                             && ps.getStopped(userId);
9510                 }
9511             }
9512             return false;
9513         }
9514
9515         @Override
9516         protected boolean isPackageForFilter(String packageName,
9517                 PackageParser.ProviderIntentInfo info) {
9518             return packageName.equals(info.provider.owner.packageName);
9519         }
9520
9521         @Override
9522         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
9523                 int match, int userId) {
9524             if (!sUserManager.exists(userId))
9525                 return null;
9526             final PackageParser.ProviderIntentInfo info = filter;
9527             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
9528                 return null;
9529             }
9530             final PackageParser.Provider provider = info.provider;
9531             if (mSafeMode && (provider.info.applicationInfo.flags
9532                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
9533                 return null;
9534             }
9535             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
9536             if (ps == null) {
9537                 return null;
9538             }
9539             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
9540                     ps.readUserState(userId), userId);
9541             if (pi == null) {
9542                 return null;
9543             }
9544             final ResolveInfo res = new ResolveInfo();
9545             res.providerInfo = pi;
9546             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
9547                 res.filter = filter;
9548             }
9549             res.priority = info.getPriority();
9550             res.preferredOrder = provider.owner.mPreferredOrder;
9551             res.match = match;
9552             res.isDefault = info.hasDefault;
9553             res.labelRes = info.labelRes;
9554             res.nonLocalizedLabel = info.nonLocalizedLabel;
9555             res.icon = info.icon;
9556             res.system = res.providerInfo.applicationInfo.isSystemApp();
9557             return res;
9558         }
9559
9560         @Override
9561         protected void sortResults(List<ResolveInfo> results) {
9562             Collections.sort(results, mResolvePrioritySorter);
9563         }
9564
9565         @Override
9566         protected void dumpFilter(PrintWriter out, String prefix,
9567                 PackageParser.ProviderIntentInfo filter) {
9568             out.print(prefix);
9569             out.print(
9570                     Integer.toHexString(System.identityHashCode(filter.provider)));
9571             out.print(' ');
9572             filter.provider.printComponentShortName(out);
9573             out.print(" filter ");
9574             out.println(Integer.toHexString(System.identityHashCode(filter)));
9575         }
9576
9577         @Override
9578         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
9579             return filter.provider;
9580         }
9581
9582         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9583             PackageParser.Provider provider = (PackageParser.Provider)label;
9584             out.print(prefix); out.print(
9585                     Integer.toHexString(System.identityHashCode(provider)));
9586                     out.print(' ');
9587                     provider.printComponentShortName(out);
9588             if (count > 1) {
9589                 out.print(" ("); out.print(count); out.print(" filters)");
9590             }
9591             out.println();
9592         }
9593
9594         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
9595                 = new ArrayMap<ComponentName, PackageParser.Provider>();
9596         private int mFlags;
9597     };
9598
9599     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
9600             new Comparator<ResolveInfo>() {
9601         public int compare(ResolveInfo r1, ResolveInfo r2) {
9602             int v1 = r1.priority;
9603             int v2 = r2.priority;
9604             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
9605             if (v1 != v2) {
9606                 return (v1 > v2) ? -1 : 1;
9607             }
9608             v1 = r1.preferredOrder;
9609             v2 = r2.preferredOrder;
9610             if (v1 != v2) {
9611                 return (v1 > v2) ? -1 : 1;
9612             }
9613             if (r1.isDefault != r2.isDefault) {
9614                 return r1.isDefault ? -1 : 1;
9615             }
9616             v1 = r1.match;
9617             v2 = r2.match;
9618             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
9619             if (v1 != v2) {
9620                 return (v1 > v2) ? -1 : 1;
9621             }
9622             if (r1.system != r2.system) {
9623                 return r1.system ? -1 : 1;
9624             }
9625             return 0;
9626         }
9627     };
9628
9629     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
9630             new Comparator<ProviderInfo>() {
9631         public int compare(ProviderInfo p1, ProviderInfo p2) {
9632             final int v1 = p1.initOrder;
9633             final int v2 = p2.initOrder;
9634             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
9635         }
9636     };
9637
9638     final void sendPackageBroadcast(final String action, final String pkg,
9639             final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver,
9640             final int[] userIds) {
9641         mHandler.post(new Runnable() {
9642             @Override
9643             public void run() {
9644                 try {
9645                     final IActivityManager am = ActivityManagerNative.getDefault();
9646                     if (am == null) return;
9647                     final int[] resolvedUserIds;
9648                     if (userIds == null) {
9649                         resolvedUserIds = am.getRunningUserIds();
9650                     } else {
9651                         resolvedUserIds = userIds;
9652                     }
9653                     for (int id : resolvedUserIds) {
9654                         final Intent intent = new Intent(action,
9655                                 pkg != null ? Uri.fromParts("package", pkg, null) : null);
9656                         if (extras != null) {
9657                             intent.putExtras(extras);
9658                         }
9659                         if (targetPkg != null) {
9660                             intent.setPackage(targetPkg);
9661                         }
9662                         // Modify the UID when posting to other users
9663                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
9664                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
9665                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
9666                             intent.putExtra(Intent.EXTRA_UID, uid);
9667                         }
9668                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
9669                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
9670                         if (DEBUG_BROADCASTS) {
9671                             RuntimeException here = new RuntimeException("here");
9672                             here.fillInStackTrace();
9673                             Slog.d(TAG, "Sending to user " + id + ": "
9674                                     + intent.toShortString(false, true, false, false)
9675                                     + " " + intent.getExtras(), here);
9676                         }
9677                         am.broadcastIntent(null, intent, null, finishedReceiver,
9678                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
9679                                 null, finishedReceiver != null, false, id);
9680                     }
9681                 } catch (RemoteException ex) {
9682                 }
9683             }
9684         });
9685     }
9686
9687     /**
9688      * Check if the external storage media is available. This is true if there
9689      * is a mounted external storage medium or if the external storage is
9690      * emulated.
9691      */
9692     private boolean isExternalMediaAvailable() {
9693         return mMediaMounted || Environment.isExternalStorageEmulated();
9694     }
9695
9696     @Override
9697     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
9698         // writer
9699         synchronized (mPackages) {
9700             if (!isExternalMediaAvailable()) {
9701                 // If the external storage is no longer mounted at this point,
9702                 // the caller may not have been able to delete all of this
9703                 // packages files and can not delete any more.  Bail.
9704                 return null;
9705             }
9706             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
9707             if (lastPackage != null) {
9708                 pkgs.remove(lastPackage);
9709             }
9710             if (pkgs.size() > 0) {
9711                 return pkgs.get(0);
9712             }
9713         }
9714         return null;
9715     }
9716
9717     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
9718         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
9719                 userId, andCode ? 1 : 0, packageName);
9720         if (mSystemReady) {
9721             msg.sendToTarget();
9722         } else {
9723             if (mPostSystemReadyMessages == null) {
9724                 mPostSystemReadyMessages = new ArrayList<>();
9725             }
9726             mPostSystemReadyMessages.add(msg);
9727         }
9728     }
9729
9730     void startCleaningPackages() {
9731         // reader
9732         synchronized (mPackages) {
9733             if (!isExternalMediaAvailable()) {
9734                 return;
9735             }
9736             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
9737                 return;
9738             }
9739         }
9740         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
9741         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
9742         IActivityManager am = ActivityManagerNative.getDefault();
9743         if (am != null) {
9744             try {
9745                 am.startService(null, intent, null, mContext.getOpPackageName(),
9746                         UserHandle.USER_OWNER);
9747             } catch (RemoteException e) {
9748             }
9749         }
9750     }
9751
9752     @Override
9753     public void installPackage(String originPath, IPackageInstallObserver2 observer,
9754             int installFlags, String installerPackageName, VerificationParams verificationParams,
9755             String packageAbiOverride) {
9756         installPackageAsUser(originPath, observer, installFlags, installerPackageName,
9757                 verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
9758     }
9759
9760     @Override
9761     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
9762             int installFlags, String installerPackageName, VerificationParams verificationParams,
9763             String packageAbiOverride, int userId) {
9764         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
9765
9766         final int callingUid = Binder.getCallingUid();
9767         enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
9768
9769         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9770             try {
9771                 if (observer != null) {
9772                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
9773                 }
9774             } catch (RemoteException re) {
9775             }
9776             return;
9777         }
9778
9779         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
9780             installFlags |= PackageManager.INSTALL_FROM_ADB;
9781
9782         } else {
9783             // Caller holds INSTALL_PACKAGES permission, so we're less strict
9784             // about installerPackageName.
9785
9786             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
9787             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
9788         }
9789
9790         UserHandle user;
9791         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
9792             user = UserHandle.ALL;
9793         } else {
9794             user = new UserHandle(userId);
9795         }
9796
9797         // Only system components can circumvent runtime permissions when installing.
9798         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
9799                 && mContext.checkCallingOrSelfPermission(Manifest.permission
9800                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
9801             throw new SecurityException("You need the "
9802                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
9803                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
9804         }
9805
9806         verificationParams.setInstallerUid(callingUid);
9807
9808         final File originFile = new File(originPath);
9809         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
9810
9811         final Message msg = mHandler.obtainMessage(INIT_COPY);
9812         msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName,
9813                 null, verificationParams, user, packageAbiOverride, null);
9814         mHandler.sendMessage(msg);
9815     }
9816
9817     void installStage(String packageName, File stagedDir, String stagedCid,
9818             IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
9819             String installerPackageName, int installerUid, UserHandle user) {
9820         final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
9821                 params.referrerUri, installerUid, null);
9822         verifParams.setInstallerUid(installerUid);
9823
9824         final OriginInfo origin;
9825         if (stagedDir != null) {
9826             origin = OriginInfo.fromStagedFile(stagedDir);
9827         } else {
9828             origin = OriginInfo.fromStagedContainer(stagedCid);
9829         }
9830
9831         final Message msg = mHandler.obtainMessage(INIT_COPY);
9832         msg.obj = new InstallParams(origin, null, observer, params.installFlags,
9833                 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride,
9834                 params.grantedRuntimePermissions);
9835         mHandler.sendMessage(msg);
9836     }
9837
9838     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
9839         Bundle extras = new Bundle(1);
9840         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
9841
9842         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
9843                 packageName, extras, null, null, new int[] {userId});
9844         try {
9845             IActivityManager am = ActivityManagerNative.getDefault();
9846             final boolean isSystem =
9847                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
9848             if (isSystem && am.isUserRunning(userId, false)) {
9849                 // The just-installed/enabled app is bundled on the system, so presumed
9850                 // to be able to run automatically without needing an explicit launch.
9851                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
9852                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
9853                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
9854                         .setPackage(packageName);
9855                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
9856                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
9857             }
9858         } catch (RemoteException e) {
9859             // shouldn't happen
9860             Slog.w(TAG, "Unable to bootstrap installed package", e);
9861         }
9862     }
9863
9864     @Override
9865     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
9866             int userId) {
9867         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
9868         PackageSetting pkgSetting;
9869         final int uid = Binder.getCallingUid();
9870         enforceCrossUserPermission(uid, userId, true, true,
9871                 "setApplicationHiddenSetting for user " + userId);
9872
9873         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
9874             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
9875             return false;
9876         }
9877
9878         long callingId = Binder.clearCallingIdentity();
9879         try {
9880             boolean sendAdded = false;
9881             boolean sendRemoved = false;
9882             // writer
9883             synchronized (mPackages) {
9884                 pkgSetting = mSettings.mPackages.get(packageName);
9885                 if (pkgSetting == null) {
9886                     return false;
9887                 }
9888                 if (pkgSetting.getHidden(userId) != hidden) {
9889                     pkgSetting.setHidden(hidden, userId);
9890                     mSettings.writePackageRestrictionsLPr(userId);
9891                     if (hidden) {
9892                         sendRemoved = true;
9893                     } else {
9894                         sendAdded = true;
9895                     }
9896                 }
9897             }
9898             if (sendAdded) {
9899                 sendPackageAddedForUser(packageName, pkgSetting, userId);
9900                 return true;
9901             }
9902             if (sendRemoved) {
9903                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
9904                         "hiding pkg");
9905                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
9906                 return true;
9907             }
9908         } finally {
9909             Binder.restoreCallingIdentity(callingId);
9910         }
9911         return false;
9912     }
9913
9914     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
9915             int userId) {
9916         final PackageRemovedInfo info = new PackageRemovedInfo();
9917         info.removedPackage = packageName;
9918         info.removedUsers = new int[] {userId};
9919         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
9920         info.sendBroadcast(false, false, false);
9921     }
9922
9923     /**
9924      * Returns true if application is not found or there was an error. Otherwise it returns
9925      * the hidden state of the package for the given user.
9926      */
9927     @Override
9928     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
9929         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
9930         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
9931                 false, "getApplicationHidden for user " + userId);
9932         PackageSetting pkgSetting;
9933         long callingId = Binder.clearCallingIdentity();
9934         try {
9935             // writer
9936             synchronized (mPackages) {
9937                 pkgSetting = mSettings.mPackages.get(packageName);
9938                 if (pkgSetting == null) {
9939                     return true;
9940                 }
9941                 return pkgSetting.getHidden(userId);
9942             }
9943         } finally {
9944             Binder.restoreCallingIdentity(callingId);
9945         }
9946     }
9947
9948     /**
9949      * @hide
9950      */
9951     @Override
9952     public int installExistingPackageAsUser(String packageName, int userId) {
9953         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
9954                 null);
9955         PackageSetting pkgSetting;
9956         final int uid = Binder.getCallingUid();
9957         enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
9958                 + userId);
9959         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9960             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
9961         }
9962
9963         long callingId = Binder.clearCallingIdentity();
9964         try {
9965             boolean sendAdded = false;
9966
9967             // writer
9968             synchronized (mPackages) {
9969                 pkgSetting = mSettings.mPackages.get(packageName);
9970                 if (pkgSetting == null) {
9971                     return PackageManager.INSTALL_FAILED_INVALID_URI;
9972                 }
9973                 if (!pkgSetting.getInstalled(userId)) {
9974                     pkgSetting.setInstalled(true, userId);
9975                     pkgSetting.setHidden(false, userId);
9976                     mSettings.writePackageRestrictionsLPr(userId);
9977                     sendAdded = true;
9978                 }
9979             }
9980
9981             if (sendAdded) {
9982                 sendPackageAddedForUser(packageName, pkgSetting, userId);
9983             }
9984         } finally {
9985             Binder.restoreCallingIdentity(callingId);
9986         }
9987
9988         return PackageManager.INSTALL_SUCCEEDED;
9989     }
9990
9991     boolean isUserRestricted(int userId, String restrictionKey) {
9992         Bundle restrictions = sUserManager.getUserRestrictions(userId);
9993         if (restrictions.getBoolean(restrictionKey, false)) {
9994             Log.w(TAG, "User is restricted: " + restrictionKey);
9995             return true;
9996         }
9997         return false;
9998     }
9999
10000     @Override
10001     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
10002         mContext.enforceCallingOrSelfPermission(
10003                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10004                 "Only package verification agents can verify applications");
10005
10006         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10007         final PackageVerificationResponse response = new PackageVerificationResponse(
10008                 verificationCode, Binder.getCallingUid());
10009         msg.arg1 = id;
10010         msg.obj = response;
10011         mHandler.sendMessage(msg);
10012     }
10013
10014     @Override
10015     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
10016             long millisecondsToDelay) {
10017         mContext.enforceCallingOrSelfPermission(
10018                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10019                 "Only package verification agents can extend verification timeouts");
10020
10021         final PackageVerificationState state = mPendingVerification.get(id);
10022         final PackageVerificationResponse response = new PackageVerificationResponse(
10023                 verificationCodeAtTimeout, Binder.getCallingUid());
10024
10025         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
10026             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
10027         }
10028         if (millisecondsToDelay < 0) {
10029             millisecondsToDelay = 0;
10030         }
10031         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
10032                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
10033             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
10034         }
10035
10036         if ((state != null) && !state.timeoutExtended()) {
10037             state.extendTimeout();
10038
10039             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10040             msg.arg1 = id;
10041             msg.obj = response;
10042             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
10043         }
10044     }
10045
10046     private void broadcastPackageVerified(int verificationId, Uri packageUri,
10047             int verificationCode, UserHandle user) {
10048         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
10049         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
10050         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10051         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10052         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
10053
10054         mContext.sendBroadcastAsUser(intent, user,
10055                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
10056     }
10057
10058     private ComponentName matchComponentForVerifier(String packageName,
10059             List<ResolveInfo> receivers) {
10060         ActivityInfo targetReceiver = null;
10061
10062         final int NR = receivers.size();
10063         for (int i = 0; i < NR; i++) {
10064             final ResolveInfo info = receivers.get(i);
10065             if (info.activityInfo == null) {
10066                 continue;
10067             }
10068
10069             if (packageName.equals(info.activityInfo.packageName)) {
10070                 targetReceiver = info.activityInfo;
10071                 break;
10072             }
10073         }
10074
10075         if (targetReceiver == null) {
10076             return null;
10077         }
10078
10079         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
10080     }
10081
10082     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
10083             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
10084         if (pkgInfo.verifiers.length == 0) {
10085             return null;
10086         }
10087
10088         final int N = pkgInfo.verifiers.length;
10089         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
10090         for (int i = 0; i < N; i++) {
10091             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
10092
10093             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
10094                     receivers);
10095             if (comp == null) {
10096                 continue;
10097             }
10098
10099             final int verifierUid = getUidForVerifier(verifierInfo);
10100             if (verifierUid == -1) {
10101                 continue;
10102             }
10103
10104             if (DEBUG_VERIFY) {
10105                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
10106                         + " with the correct signature");
10107             }
10108             sufficientVerifiers.add(comp);
10109             verificationState.addSufficientVerifier(verifierUid);
10110         }
10111
10112         return sufficientVerifiers;
10113     }
10114
10115     private int getUidForVerifier(VerifierInfo verifierInfo) {
10116         synchronized (mPackages) {
10117             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
10118             if (pkg == null) {
10119                 return -1;
10120             } else if (pkg.mSignatures.length != 1) {
10121                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10122                         + " has more than one signature; ignoring");
10123                 return -1;
10124             }
10125
10126             /*
10127              * If the public key of the package's signature does not match
10128              * our expected public key, then this is a different package and
10129              * we should skip.
10130              */
10131
10132             final byte[] expectedPublicKey;
10133             try {
10134                 final Signature verifierSig = pkg.mSignatures[0];
10135                 final PublicKey publicKey = verifierSig.getPublicKey();
10136                 expectedPublicKey = publicKey.getEncoded();
10137             } catch (CertificateException e) {
10138                 return -1;
10139             }
10140
10141             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
10142
10143             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
10144                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10145                         + " does not have the expected public key; ignoring");
10146                 return -1;
10147             }
10148
10149             return pkg.applicationInfo.uid;
10150         }
10151     }
10152
10153     @Override
10154     public void finishPackageInstall(int token) {
10155         enforceSystemOrRoot("Only the system is allowed to finish installs");
10156
10157         if (DEBUG_INSTALL) {
10158             Slog.v(TAG, "BM finishing package install for " + token);
10159         }
10160
10161         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10162         mHandler.sendMessage(msg);
10163     }
10164
10165     /**
10166      * Get the verification agent timeout.
10167      *
10168      * @return verification timeout in milliseconds
10169      */
10170     private long getVerificationTimeout() {
10171         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
10172                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
10173                 DEFAULT_VERIFICATION_TIMEOUT);
10174     }
10175
10176     /**
10177      * Get the default verification agent response code.
10178      *
10179      * @return default verification response code
10180      */
10181     private int getDefaultVerificationResponse() {
10182         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10183                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
10184                 DEFAULT_VERIFICATION_RESPONSE);
10185     }
10186
10187     /**
10188      * Check whether or not package verification has been enabled.
10189      *
10190      * @return true if verification should be performed
10191      */
10192     private boolean isVerificationEnabled(int userId, int installFlags) {
10193         if (!DEFAULT_VERIFY_ENABLE) {
10194             return false;
10195         }
10196
10197         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
10198
10199         // Check if installing from ADB
10200         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
10201             // Do not run verification in a test harness environment
10202             if (ActivityManager.isRunningInTestHarness()) {
10203                 return false;
10204             }
10205             if (ensureVerifyAppsEnabled) {
10206                 return true;
10207             }
10208             // Check if the developer does not want package verification for ADB installs
10209             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10210                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
10211                 return false;
10212             }
10213         }
10214
10215         if (ensureVerifyAppsEnabled) {
10216             return true;
10217         }
10218
10219         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10220                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
10221     }
10222
10223     @Override
10224     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
10225             throws RemoteException {
10226         mContext.enforceCallingOrSelfPermission(
10227                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
10228                 "Only intentfilter verification agents can verify applications");
10229
10230         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
10231         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
10232                 Binder.getCallingUid(), verificationCode, failedDomains);
10233         msg.arg1 = id;
10234         msg.obj = response;
10235         mHandler.sendMessage(msg);
10236     }
10237
10238     @Override
10239     public int getIntentVerificationStatus(String packageName, int userId) {
10240         synchronized (mPackages) {
10241             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
10242         }
10243     }
10244
10245     @Override
10246     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
10247         mContext.enforceCallingOrSelfPermission(
10248                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10249
10250         boolean result = false;
10251         synchronized (mPackages) {
10252             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
10253         }
10254         if (result) {
10255             scheduleWritePackageRestrictionsLocked(userId);
10256         }
10257         return result;
10258     }
10259
10260     @Override
10261     public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
10262         synchronized (mPackages) {
10263             return mSettings.getIntentFilterVerificationsLPr(packageName);
10264         }
10265     }
10266
10267     @Override
10268     public List<IntentFilter> getAllIntentFilters(String packageName) {
10269         if (TextUtils.isEmpty(packageName)) {
10270             return Collections.<IntentFilter>emptyList();
10271         }
10272         synchronized (mPackages) {
10273             PackageParser.Package pkg = mPackages.get(packageName);
10274             if (pkg == null || pkg.activities == null) {
10275                 return Collections.<IntentFilter>emptyList();
10276             }
10277             final int count = pkg.activities.size();
10278             ArrayList<IntentFilter> result = new ArrayList<>();
10279             for (int n=0; n<count; n++) {
10280                 PackageParser.Activity activity = pkg.activities.get(n);
10281                 if (activity.intents != null || activity.intents.size() > 0) {
10282                     result.addAll(activity.intents);
10283                 }
10284             }
10285             return result;
10286         }
10287     }
10288
10289     @Override
10290     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
10291         mContext.enforceCallingOrSelfPermission(
10292                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10293
10294         synchronized (mPackages) {
10295             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
10296             if (packageName != null) {
10297                 result |= updateIntentVerificationStatus(packageName,
10298                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
10299                         userId);
10300                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
10301                         packageName, userId);
10302             }
10303             return result;
10304         }
10305     }
10306
10307     @Override
10308     public String getDefaultBrowserPackageName(int userId) {
10309         synchronized (mPackages) {
10310             return mSettings.getDefaultBrowserPackageNameLPw(userId);
10311         }
10312     }
10313
10314     /**
10315      * Get the "allow unknown sources" setting.
10316      *
10317      * @return the current "allow unknown sources" setting
10318      */
10319     private int getUnknownSourcesSettings() {
10320         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10321                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
10322                 -1);
10323     }
10324
10325     @Override
10326     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
10327         final int uid = Binder.getCallingUid();
10328         // writer
10329         synchronized (mPackages) {
10330             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
10331             if (targetPackageSetting == null) {
10332                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
10333             }
10334
10335             PackageSetting installerPackageSetting;
10336             if (installerPackageName != null) {
10337                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
10338                 if (installerPackageSetting == null) {
10339                     throw new IllegalArgumentException("Unknown installer package: "
10340                             + installerPackageName);
10341                 }
10342             } else {
10343                 installerPackageSetting = null;
10344             }
10345
10346             Signature[] callerSignature;
10347             Object obj = mSettings.getUserIdLPr(uid);
10348             if (obj != null) {
10349                 if (obj instanceof SharedUserSetting) {
10350                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
10351                 } else if (obj instanceof PackageSetting) {
10352                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
10353                 } else {
10354                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
10355                 }
10356             } else {
10357                 throw new SecurityException("Unknown calling uid " + uid);
10358             }
10359
10360             // Verify: can't set installerPackageName to a package that is
10361             // not signed with the same cert as the caller.
10362             if (installerPackageSetting != null) {
10363                 if (compareSignatures(callerSignature,
10364                         installerPackageSetting.signatures.mSignatures)
10365                         != PackageManager.SIGNATURE_MATCH) {
10366                     throw new SecurityException(
10367                             "Caller does not have same cert as new installer package "
10368                             + installerPackageName);
10369                 }
10370             }
10371
10372             // Verify: if target already has an installer package, it must
10373             // be signed with the same cert as the caller.
10374             if (targetPackageSetting.installerPackageName != null) {
10375                 PackageSetting setting = mSettings.mPackages.get(
10376                         targetPackageSetting.installerPackageName);
10377                 // If the currently set package isn't valid, then it's always
10378                 // okay to change it.
10379                 if (setting != null) {
10380                     if (compareSignatures(callerSignature,
10381                             setting.signatures.mSignatures)
10382                             != PackageManager.SIGNATURE_MATCH) {
10383                         throw new SecurityException(
10384                                 "Caller does not have same cert as old installer package "
10385                                 + targetPackageSetting.installerPackageName);
10386                     }
10387                 }
10388             }
10389
10390             // Okay!
10391             targetPackageSetting.installerPackageName = installerPackageName;
10392             scheduleWriteSettingsLocked();
10393         }
10394     }
10395
10396     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
10397         // Queue up an async operation since the package installation may take a little while.
10398         mHandler.post(new Runnable() {
10399             public void run() {
10400                 mHandler.removeCallbacks(this);
10401                  // Result object to be returned
10402                 PackageInstalledInfo res = new PackageInstalledInfo();
10403                 res.returnCode = currentStatus;
10404                 res.uid = -1;
10405                 res.pkg = null;
10406                 res.removedInfo = new PackageRemovedInfo();
10407                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10408                     args.doPreInstall(res.returnCode);
10409                     synchronized (mInstallLock) {
10410                         installPackageLI(args, res);
10411                     }
10412                     args.doPostInstall(res.returnCode, res.uid);
10413                 }
10414
10415                 // A restore should be performed at this point if (a) the install
10416                 // succeeded, (b) the operation is not an update, and (c) the new
10417                 // package has not opted out of backup participation.
10418                 final boolean update = res.removedInfo.removedPackage != null;
10419                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
10420                 boolean doRestore = !update
10421                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
10422
10423                 // Set up the post-install work request bookkeeping.  This will be used
10424                 // and cleaned up by the post-install event handling regardless of whether
10425                 // there's a restore pass performed.  Token values are >= 1.
10426                 int token;
10427                 if (mNextInstallToken < 0) mNextInstallToken = 1;
10428                 token = mNextInstallToken++;
10429
10430                 PostInstallData data = new PostInstallData(args, res);
10431                 mRunningInstalls.put(token, data);
10432                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
10433
10434                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
10435                     // Pass responsibility to the Backup Manager.  It will perform a
10436                     // restore if appropriate, then pass responsibility back to the
10437                     // Package Manager to run the post-install observer callbacks
10438                     // and broadcasts.
10439                     IBackupManager bm = IBackupManager.Stub.asInterface(
10440                             ServiceManager.getService(Context.BACKUP_SERVICE));
10441                     if (bm != null) {
10442                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
10443                                 + " to BM for possible restore");
10444                         try {
10445                             if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
10446                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
10447                             } else {
10448                                 doRestore = false;
10449                             }
10450                         } catch (RemoteException e) {
10451                             // can't happen; the backup manager is local
10452                         } catch (Exception e) {
10453                             Slog.e(TAG, "Exception trying to enqueue restore", e);
10454                             doRestore = false;
10455                         }
10456                     } else {
10457                         Slog.e(TAG, "Backup Manager not found!");
10458                         doRestore = false;
10459                     }
10460                 }
10461
10462                 if (!doRestore) {
10463                     // No restore possible, or the Backup Manager was mysteriously not
10464                     // available -- just fire the post-install work request directly.
10465                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
10466                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10467                     mHandler.sendMessage(msg);
10468                 }
10469             }
10470         });
10471     }
10472
10473     private abstract class HandlerParams {
10474         private static final int MAX_RETRIES = 4;
10475
10476         /**
10477          * Number of times startCopy() has been attempted and had a non-fatal
10478          * error.
10479          */
10480         private int mRetries = 0;
10481
10482         /** User handle for the user requesting the information or installation. */
10483         private final UserHandle mUser;
10484
10485         HandlerParams(UserHandle user) {
10486             mUser = user;
10487         }
10488
10489         UserHandle getUser() {
10490             return mUser;
10491         }
10492
10493         final boolean startCopy() {
10494             boolean res;
10495             try {
10496                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
10497
10498                 if (++mRetries > MAX_RETRIES) {
10499                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
10500                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
10501                     handleServiceError();
10502                     return false;
10503                 } else {
10504                     handleStartCopy();
10505                     res = true;
10506                 }
10507             } catch (RemoteException e) {
10508                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
10509                 mHandler.sendEmptyMessage(MCS_RECONNECT);
10510                 res = false;
10511             }
10512             handleReturnCode();
10513             return res;
10514         }
10515
10516         final void serviceError() {
10517             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
10518             handleServiceError();
10519             handleReturnCode();
10520         }
10521
10522         abstract void handleStartCopy() throws RemoteException;
10523         abstract void handleServiceError();
10524         abstract void handleReturnCode();
10525     }
10526
10527     class MeasureParams extends HandlerParams {
10528         private final PackageStats mStats;
10529         private boolean mSuccess;
10530
10531         private final IPackageStatsObserver mObserver;
10532
10533         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
10534             super(new UserHandle(stats.userHandle));
10535             mObserver = observer;
10536             mStats = stats;
10537         }
10538
10539         @Override
10540         public String toString() {
10541             return "MeasureParams{"
10542                 + Integer.toHexString(System.identityHashCode(this))
10543                 + " " + mStats.packageName + "}";
10544         }
10545
10546         @Override
10547         void handleStartCopy() throws RemoteException {
10548             synchronized (mInstallLock) {
10549                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
10550             }
10551
10552             if (mSuccess) {
10553                 final boolean mounted;
10554                 if (Environment.isExternalStorageEmulated()) {
10555                     mounted = true;
10556                 } else {
10557                     final String status = Environment.getExternalStorageState();
10558                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
10559                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
10560                 }
10561
10562                 if (mounted) {
10563                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
10564
10565                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
10566                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
10567
10568                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
10569                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
10570
10571                     // Always subtract cache size, since it's a subdirectory
10572                     mStats.externalDataSize -= mStats.externalCacheSize;
10573
10574                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
10575                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
10576
10577                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
10578                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
10579                 }
10580             }
10581         }
10582
10583         @Override
10584         void handleReturnCode() {
10585             if (mObserver != null) {
10586                 try {
10587                     mObserver.onGetStatsCompleted(mStats, mSuccess);
10588                 } catch (RemoteException e) {
10589                     Slog.i(TAG, "Observer no longer exists.");
10590                 }
10591             }
10592         }
10593
10594         @Override
10595         void handleServiceError() {
10596             Slog.e(TAG, "Could not measure application " + mStats.packageName
10597                             + " external storage");
10598         }
10599     }
10600
10601     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
10602             throws RemoteException {
10603         long result = 0;
10604         for (File path : paths) {
10605             result += mcs.calculateDirectorySize(path.getAbsolutePath());
10606         }
10607         return result;
10608     }
10609
10610     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
10611         for (File path : paths) {
10612             try {
10613                 mcs.clearDirectory(path.getAbsolutePath());
10614             } catch (RemoteException e) {
10615             }
10616         }
10617     }
10618
10619     static class OriginInfo {
10620         /**
10621          * Location where install is coming from, before it has been
10622          * copied/renamed into place. This could be a single monolithic APK
10623          * file, or a cluster directory. This location may be untrusted.
10624          */
10625         final File file;
10626         final String cid;
10627
10628         /**
10629          * Flag indicating that {@link #file} or {@link #cid} has already been
10630          * staged, meaning downstream users don't need to defensively copy the
10631          * contents.
10632          */
10633         final boolean staged;
10634
10635         /**
10636          * Flag indicating that {@link #file} or {@link #cid} is an already
10637          * installed app that is being moved.
10638          */
10639         final boolean existing;
10640
10641         final String resolvedPath;
10642         final File resolvedFile;
10643
10644         static OriginInfo fromNothing() {
10645             return new OriginInfo(null, null, false, false);
10646         }
10647
10648         static OriginInfo fromUntrustedFile(File file) {
10649             return new OriginInfo(file, null, false, false);
10650         }
10651
10652         static OriginInfo fromExistingFile(File file) {
10653             return new OriginInfo(file, null, false, true);
10654         }
10655
10656         static OriginInfo fromStagedFile(File file) {
10657             return new OriginInfo(file, null, true, false);
10658         }
10659
10660         static OriginInfo fromStagedContainer(String cid) {
10661             return new OriginInfo(null, cid, true, false);
10662         }
10663
10664         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
10665             this.file = file;
10666             this.cid = cid;
10667             this.staged = staged;
10668             this.existing = existing;
10669
10670             if (cid != null) {
10671                 resolvedPath = PackageHelper.getSdDir(cid);
10672                 resolvedFile = new File(resolvedPath);
10673             } else if (file != null) {
10674                 resolvedPath = file.getAbsolutePath();
10675                 resolvedFile = file;
10676             } else {
10677                 resolvedPath = null;
10678                 resolvedFile = null;
10679             }
10680         }
10681     }
10682
10683     class MoveInfo {
10684         final int moveId;
10685         final String fromUuid;
10686         final String toUuid;
10687         final String packageName;
10688         final String dataAppName;
10689         final int appId;
10690         final String seinfo;
10691
10692         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
10693                 String dataAppName, int appId, String seinfo) {
10694             this.moveId = moveId;
10695             this.fromUuid = fromUuid;
10696             this.toUuid = toUuid;
10697             this.packageName = packageName;
10698             this.dataAppName = dataAppName;
10699             this.appId = appId;
10700             this.seinfo = seinfo;
10701         }
10702     }
10703
10704     class InstallParams extends HandlerParams {
10705         final OriginInfo origin;
10706         final MoveInfo move;
10707         final IPackageInstallObserver2 observer;
10708         int installFlags;
10709         final String installerPackageName;
10710         final String volumeUuid;
10711         final VerificationParams verificationParams;
10712         private InstallArgs mArgs;
10713         private int mRet;
10714         final String packageAbiOverride;
10715         final String[] grantedRuntimePermissions;
10716
10717
10718         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
10719                 int installFlags, String installerPackageName, String volumeUuid,
10720                 VerificationParams verificationParams, UserHandle user, String packageAbiOverride,
10721                 String[] grantedPermissions) {
10722             super(user);
10723             this.origin = origin;
10724             this.move = move;
10725             this.observer = observer;
10726             this.installFlags = installFlags;
10727             this.installerPackageName = installerPackageName;
10728             this.volumeUuid = volumeUuid;
10729             this.verificationParams = verificationParams;
10730             this.packageAbiOverride = packageAbiOverride;
10731             this.grantedRuntimePermissions = grantedPermissions;
10732         }
10733
10734         @Override
10735         public String toString() {
10736             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
10737                     + " file=" + origin.file + " cid=" + origin.cid + "}";
10738         }
10739
10740         public ManifestDigest getManifestDigest() {
10741             if (verificationParams == null) {
10742                 return null;
10743             }
10744             return verificationParams.getManifestDigest();
10745         }
10746
10747         private int installLocationPolicy(PackageInfoLite pkgLite) {
10748             String packageName = pkgLite.packageName;
10749             int installLocation = pkgLite.installLocation;
10750             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10751             // reader
10752             synchronized (mPackages) {
10753                 PackageParser.Package pkg = mPackages.get(packageName);
10754                 if (pkg != null) {
10755                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10756                         // Check for downgrading.
10757                         if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
10758                             try {
10759                                 checkDowngrade(pkg, pkgLite);
10760                             } catch (PackageManagerException e) {
10761                                 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
10762                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
10763                             }
10764                         }
10765                         // Check for updated system application.
10766                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10767                             if (onSd) {
10768                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
10769                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
10770                             }
10771                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10772                         } else {
10773                             if (onSd) {
10774                                 // Install flag overrides everything.
10775                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10776                             }
10777                             // If current upgrade specifies particular preference
10778                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
10779                                 // Application explicitly specified internal.
10780                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10781                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
10782                                 // App explictly prefers external. Let policy decide
10783                             } else {
10784                                 // Prefer previous location
10785                                 if (isExternal(pkg)) {
10786                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10787                                 }
10788                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10789                             }
10790                         }
10791                     } else {
10792                         // Invalid install. Return error code
10793                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
10794                     }
10795                 }
10796             }
10797             // All the special cases have been taken care of.
10798             // Return result based on recommended install location.
10799             if (onSd) {
10800                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10801             }
10802             return pkgLite.recommendedInstallLocation;
10803         }
10804
10805         /*
10806          * Invoke remote method to get package information and install
10807          * location values. Override install location based on default
10808          * policy if needed and then create install arguments based
10809          * on the install location.
10810          */
10811         public void handleStartCopy() throws RemoteException {
10812             int ret = PackageManager.INSTALL_SUCCEEDED;
10813
10814             // If we're already staged, we've firmly committed to an install location
10815             if (origin.staged) {
10816                 if (origin.file != null) {
10817                     installFlags |= PackageManager.INSTALL_INTERNAL;
10818                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
10819                 } else if (origin.cid != null) {
10820                     installFlags |= PackageManager.INSTALL_EXTERNAL;
10821                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
10822                 } else {
10823                     throw new IllegalStateException("Invalid stage location");
10824                 }
10825             }
10826
10827             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10828             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
10829
10830             PackageInfoLite pkgLite = null;
10831
10832             if (onInt && onSd) {
10833                 // Check if both bits are set.
10834                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
10835                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
10836             } else {
10837                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
10838                         packageAbiOverride);
10839
10840                 /*
10841                  * If we have too little free space, try to free cache
10842                  * before giving up.
10843                  */
10844                 if (!origin.staged && pkgLite.recommendedInstallLocation
10845                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
10846                     // TODO: focus freeing disk space on the target device
10847                     final StorageManager storage = StorageManager.from(mContext);
10848                     final long lowThreshold = storage.getStorageLowBytes(
10849                             Environment.getDataDirectory());
10850
10851                     final long sizeBytes = mContainerService.calculateInstalledSize(
10852                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
10853
10854                     if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) {
10855                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
10856                                 installFlags, packageAbiOverride);
10857                     }
10858
10859                     /*
10860                      * The cache free must have deleted the file we
10861                      * downloaded to install.
10862                      *
10863                      * TODO: fix the "freeCache" call to not delete
10864                      *       the file we care about.
10865                      */
10866                     if (pkgLite.recommendedInstallLocation
10867                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
10868                         pkgLite.recommendedInstallLocation
10869                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
10870                     }
10871                 }
10872             }
10873
10874             if (ret == PackageManager.INSTALL_SUCCEEDED) {
10875                 int loc = pkgLite.recommendedInstallLocation;
10876                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
10877                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
10878                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
10879                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
10880                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
10881                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
10882                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
10883                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
10884                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
10885                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
10886                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
10887                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
10888                 } else {
10889                     // Override with defaults if needed.
10890                     loc = installLocationPolicy(pkgLite);
10891                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
10892                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
10893                     } else if (!onSd && !onInt) {
10894                         // Override install location with flags
10895                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
10896                             // Set the flag to install on external media.
10897                             installFlags |= PackageManager.INSTALL_EXTERNAL;
10898                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
10899                         } else {
10900                             // Make sure the flag for installing on external
10901                             // media is unset
10902                             installFlags |= PackageManager.INSTALL_INTERNAL;
10903                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
10904                         }
10905                     }
10906                 }
10907             }
10908
10909             final InstallArgs args = createInstallArgs(this);
10910             mArgs = args;
10911
10912             if (ret == PackageManager.INSTALL_SUCCEEDED) {
10913                  /*
10914                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
10915                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
10916                  */
10917                 int userIdentifier = getUser().getIdentifier();
10918                 if (userIdentifier == UserHandle.USER_ALL
10919                         && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
10920                     userIdentifier = UserHandle.USER_OWNER;
10921                 }
10922
10923                 /*
10924                  * Determine if we have any installed package verifiers. If we
10925                  * do, then we'll defer to them to verify the packages.
10926                  */
10927                 final int requiredUid = mRequiredVerifierPackage == null ? -1
10928                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
10929                 if (!origin.existing && requiredUid != -1
10930                         && isVerificationEnabled(userIdentifier, installFlags)) {
10931                     final Intent verification = new Intent(
10932                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
10933                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10934                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
10935                             PACKAGE_MIME_TYPE);
10936                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10937
10938                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
10939                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
10940                             0 /* TODO: Which userId? */);
10941
10942                     if (DEBUG_VERIFY) {
10943                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
10944                                 + verification.toString() + " with " + pkgLite.verifiers.length
10945                                 + " optional verifiers");
10946                     }
10947
10948                     final int verificationId = mPendingVerificationToken++;
10949
10950                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10951
10952                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
10953                             installerPackageName);
10954
10955                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
10956                             installFlags);
10957
10958                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
10959                             pkgLite.packageName);
10960
10961                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
10962                             pkgLite.versionCode);
10963
10964                     if (verificationParams != null) {
10965                         if (verificationParams.getVerificationURI() != null) {
10966                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
10967                                  verificationParams.getVerificationURI());
10968                         }
10969                         if (verificationParams.getOriginatingURI() != null) {
10970                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
10971                                   verificationParams.getOriginatingURI());
10972                         }
10973                         if (verificationParams.getReferrer() != null) {
10974                             verification.putExtra(Intent.EXTRA_REFERRER,
10975                                   verificationParams.getReferrer());
10976                         }
10977                         if (verificationParams.getOriginatingUid() >= 0) {
10978                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
10979                                   verificationParams.getOriginatingUid());
10980                         }
10981                         if (verificationParams.getInstallerUid() >= 0) {
10982                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
10983                                   verificationParams.getInstallerUid());
10984                         }
10985                     }
10986
10987                     final PackageVerificationState verificationState = new PackageVerificationState(
10988                             requiredUid, args);
10989
10990                     mPendingVerification.append(verificationId, verificationState);
10991
10992                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
10993                             receivers, verificationState);
10994
10995                     // Apps installed for "all" users use the device owner to verify the app
10996                     UserHandle verifierUser = getUser();
10997                     if (verifierUser == UserHandle.ALL) {
10998                         verifierUser = UserHandle.OWNER;
10999                     }
11000
11001                     /*
11002                      * If any sufficient verifiers were listed in the package
11003                      * manifest, attempt to ask them.
11004                      */
11005                     if (sufficientVerifiers != null) {
11006                         final int N = sufficientVerifiers.size();
11007                         if (N == 0) {
11008                             Slog.i(TAG, "Additional verifiers required, but none installed.");
11009                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
11010                         } else {
11011                             for (int i = 0; i < N; i++) {
11012                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
11013
11014                                 final Intent sufficientIntent = new Intent(verification);
11015                                 sufficientIntent.setComponent(verifierComponent);
11016                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
11017                             }
11018                         }
11019                     }
11020
11021                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
11022                             mRequiredVerifierPackage, receivers);
11023                     if (ret == PackageManager.INSTALL_SUCCEEDED
11024                             && mRequiredVerifierPackage != null) {
11025                         /*
11026                          * Send the intent to the required verification agent,
11027                          * but only start the verification timeout after the
11028                          * target BroadcastReceivers have run.
11029                          */
11030                         verification.setComponent(requiredVerifierComponent);
11031                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
11032                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11033                                 new BroadcastReceiver() {
11034                                     @Override
11035                                     public void onReceive(Context context, Intent intent) {
11036                                         final Message msg = mHandler
11037                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
11038                                         msg.arg1 = verificationId;
11039                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
11040                                     }
11041                                 }, null, 0, null, null);
11042
11043                         /*
11044                          * We don't want the copy to proceed until verification
11045                          * succeeds, so null out this field.
11046                          */
11047                         mArgs = null;
11048                     }
11049                 } else {
11050                     /*
11051                      * No package verification is enabled, so immediately start
11052                      * the remote call to initiate copy using temporary file.
11053                      */
11054                     ret = args.copyApk(mContainerService, true);
11055                 }
11056             }
11057
11058             mRet = ret;
11059         }
11060
11061         @Override
11062         void handleReturnCode() {
11063             // If mArgs is null, then MCS couldn't be reached. When it
11064             // reconnects, it will try again to install. At that point, this
11065             // will succeed.
11066             if (mArgs != null) {
11067                 processPendingInstall(mArgs, mRet);
11068             }
11069         }
11070
11071         @Override
11072         void handleServiceError() {
11073             mArgs = createInstallArgs(this);
11074             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11075         }
11076
11077         public boolean isForwardLocked() {
11078             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11079         }
11080     }
11081
11082     /**
11083      * Used during creation of InstallArgs
11084      *
11085      * @param installFlags package installation flags
11086      * @return true if should be installed on external storage
11087      */
11088     private static boolean installOnExternalAsec(int installFlags) {
11089         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
11090             return false;
11091         }
11092         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
11093             return true;
11094         }
11095         return false;
11096     }
11097
11098     /**
11099      * Used during creation of InstallArgs
11100      *
11101      * @param installFlags package installation flags
11102      * @return true if should be installed as forward locked
11103      */
11104     private static boolean installForwardLocked(int installFlags) {
11105         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11106     }
11107
11108     private InstallArgs createInstallArgs(InstallParams params) {
11109         if (params.move != null) {
11110             return new MoveInstallArgs(params);
11111         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
11112             return new AsecInstallArgs(params);
11113         } else {
11114             return new FileInstallArgs(params);
11115         }
11116     }
11117
11118     /**
11119      * Create args that describe an existing installed package. Typically used
11120      * when cleaning up old installs, or used as a move source.
11121      */
11122     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
11123             String resourcePath, String[] instructionSets) {
11124         final boolean isInAsec;
11125         if (installOnExternalAsec(installFlags)) {
11126             /* Apps on SD card are always in ASEC containers. */
11127             isInAsec = true;
11128         } else if (installForwardLocked(installFlags)
11129                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
11130             /*
11131              * Forward-locked apps are only in ASEC containers if they're the
11132              * new style
11133              */
11134             isInAsec = true;
11135         } else {
11136             isInAsec = false;
11137         }
11138
11139         if (isInAsec) {
11140             return new AsecInstallArgs(codePath, instructionSets,
11141                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
11142         } else {
11143             return new FileInstallArgs(codePath, resourcePath, instructionSets);
11144         }
11145     }
11146
11147     static abstract class InstallArgs {
11148         /** @see InstallParams#origin */
11149         final OriginInfo origin;
11150         /** @see InstallParams#move */
11151         final MoveInfo move;
11152
11153         final IPackageInstallObserver2 observer;
11154         // Always refers to PackageManager flags only
11155         final int installFlags;
11156         final String installerPackageName;
11157         final String volumeUuid;
11158         final ManifestDigest manifestDigest;
11159         final UserHandle user;
11160         final String abiOverride;
11161         final String[] installGrantPermissions;
11162
11163         // The list of instruction sets supported by this app. This is currently
11164         // only used during the rmdex() phase to clean up resources. We can get rid of this
11165         // if we move dex files under the common app path.
11166         /* nullable */ String[] instructionSets;
11167
11168         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
11169                 int installFlags, String installerPackageName, String volumeUuid,
11170                 ManifestDigest manifestDigest, UserHandle user, String[] instructionSets,
11171                 String abiOverride, String[] installGrantPermissions) {
11172             this.origin = origin;
11173             this.move = move;
11174             this.installFlags = installFlags;
11175             this.observer = observer;
11176             this.installerPackageName = installerPackageName;
11177             this.volumeUuid = volumeUuid;
11178             this.manifestDigest = manifestDigest;
11179             this.user = user;
11180             this.instructionSets = instructionSets;
11181             this.abiOverride = abiOverride;
11182             this.installGrantPermissions = installGrantPermissions;
11183         }
11184
11185         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
11186         abstract int doPreInstall(int status);
11187
11188         /**
11189          * Rename package into final resting place. All paths on the given
11190          * scanned package should be updated to reflect the rename.
11191          */
11192         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
11193         abstract int doPostInstall(int status, int uid);
11194
11195         /** @see PackageSettingBase#codePathString */
11196         abstract String getCodePath();
11197         /** @see PackageSettingBase#resourcePathString */
11198         abstract String getResourcePath();
11199
11200         // Need installer lock especially for dex file removal.
11201         abstract void cleanUpResourcesLI();
11202         abstract boolean doPostDeleteLI(boolean delete);
11203
11204         /**
11205          * Called before the source arguments are copied. This is used mostly
11206          * for MoveParams when it needs to read the source file to put it in the
11207          * destination.
11208          */
11209         int doPreCopy() {
11210             return PackageManager.INSTALL_SUCCEEDED;
11211         }
11212
11213         /**
11214          * Called after the source arguments are copied. This is used mostly for
11215          * MoveParams when it needs to read the source file to put it in the
11216          * destination.
11217          */
11218         int doPostCopy(int uid) {
11219             return PackageManager.INSTALL_SUCCEEDED;
11220         }
11221
11222         protected boolean isFwdLocked() {
11223             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11224         }
11225
11226         protected boolean isExternalAsec() {
11227             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11228         }
11229
11230         UserHandle getUser() {
11231             return user;
11232         }
11233     }
11234
11235     private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
11236         if (!allCodePaths.isEmpty()) {
11237             if (instructionSets == null) {
11238                 throw new IllegalStateException("instructionSet == null");
11239             }
11240             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
11241             for (String codePath : allCodePaths) {
11242                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
11243                     int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
11244                     if (retCode < 0) {
11245                         Slog.w(TAG, "Couldn't remove dex file for package: "
11246                                 + " at location " + codePath + ", retcode=" + retCode);
11247                         // we don't consider this to be a failure of the core package deletion
11248                     }
11249                 }
11250             }
11251         }
11252     }
11253
11254     /**
11255      * Logic to handle installation of non-ASEC applications, including copying
11256      * and renaming logic.
11257      */
11258     class FileInstallArgs extends InstallArgs {
11259         private File codeFile;
11260         private File resourceFile;
11261
11262         // Example topology:
11263         // /data/app/com.example/base.apk
11264         // /data/app/com.example/split_foo.apk
11265         // /data/app/com.example/lib/arm/libfoo.so
11266         // /data/app/com.example/lib/arm64/libfoo.so
11267         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
11268
11269         /** New install */
11270         FileInstallArgs(InstallParams params) {
11271             super(params.origin, params.move, params.observer, params.installFlags,
11272                     params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
11273                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11274                     params.grantedRuntimePermissions);
11275             if (isFwdLocked()) {
11276                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
11277             }
11278         }
11279
11280         /** Existing install */
11281         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
11282             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets,
11283                     null, null);
11284             this.codeFile = (codePath != null) ? new File(codePath) : null;
11285             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
11286         }
11287
11288         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11289             if (origin.staged) {
11290                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
11291                 codeFile = origin.file;
11292                 resourceFile = origin.file;
11293                 return PackageManager.INSTALL_SUCCEEDED;
11294             }
11295
11296             try {
11297                 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid);
11298                 codeFile = tempDir;
11299                 resourceFile = tempDir;
11300             } catch (IOException e) {
11301                 Slog.w(TAG, "Failed to create copy file: " + e);
11302                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11303             }
11304
11305             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
11306                 @Override
11307                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
11308                     if (!FileUtils.isValidExtFilename(name)) {
11309                         throw new IllegalArgumentException("Invalid filename: " + name);
11310                     }
11311                     try {
11312                         final File file = new File(codeFile, name);
11313                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
11314                                 O_RDWR | O_CREAT, 0644);
11315                         Os.chmod(file.getAbsolutePath(), 0644);
11316                         return new ParcelFileDescriptor(fd);
11317                     } catch (ErrnoException e) {
11318                         throw new RemoteException("Failed to open: " + e.getMessage());
11319                     }
11320                 }
11321             };
11322
11323             int ret = PackageManager.INSTALL_SUCCEEDED;
11324             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
11325             if (ret != PackageManager.INSTALL_SUCCEEDED) {
11326                 Slog.e(TAG, "Failed to copy package");
11327                 return ret;
11328             }
11329
11330             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
11331             NativeLibraryHelper.Handle handle = null;
11332             try {
11333                 handle = NativeLibraryHelper.Handle.create(codeFile);
11334                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
11335                         abiOverride);
11336             } catch (IOException e) {
11337                 Slog.e(TAG, "Copying native libraries failed", e);
11338                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11339             } finally {
11340                 IoUtils.closeQuietly(handle);
11341             }
11342
11343             return ret;
11344         }
11345
11346         int doPreInstall(int status) {
11347             if (status != PackageManager.INSTALL_SUCCEEDED) {
11348                 cleanUp();
11349             }
11350             return status;
11351         }
11352
11353         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11354             if (status != PackageManager.INSTALL_SUCCEEDED) {
11355                 cleanUp();
11356                 return false;
11357             }
11358
11359             final File targetDir = codeFile.getParentFile();
11360             final File beforeCodeFile = codeFile;
11361             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
11362
11363             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
11364             try {
11365                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
11366             } catch (ErrnoException e) {
11367                 Slog.w(TAG, "Failed to rename", e);
11368                 return false;
11369             }
11370
11371             if (!SELinux.restoreconRecursive(afterCodeFile)) {
11372                 Slog.w(TAG, "Failed to restorecon");
11373                 return false;
11374             }
11375
11376             // Reflect the rename internally
11377             codeFile = afterCodeFile;
11378             resourceFile = afterCodeFile;
11379
11380             // Reflect the rename in scanned details
11381             pkg.codePath = afterCodeFile.getAbsolutePath();
11382             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11383                     pkg.baseCodePath);
11384             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11385                     pkg.splitCodePaths);
11386
11387             // Reflect the rename in app info
11388             pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11389             pkg.applicationInfo.setCodePath(pkg.codePath);
11390             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11391             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11392             pkg.applicationInfo.setResourcePath(pkg.codePath);
11393             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11394             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11395
11396             return true;
11397         }
11398
11399         int doPostInstall(int status, int uid) {
11400             if (status != PackageManager.INSTALL_SUCCEEDED) {
11401                 cleanUp();
11402             }
11403             return status;
11404         }
11405
11406         @Override
11407         String getCodePath() {
11408             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11409         }
11410
11411         @Override
11412         String getResourcePath() {
11413             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11414         }
11415
11416         private boolean cleanUp() {
11417             if (codeFile == null || !codeFile.exists()) {
11418                 return false;
11419             }
11420
11421             if (codeFile.isDirectory()) {
11422                 mInstaller.rmPackageDir(codeFile.getAbsolutePath());
11423             } else {
11424                 codeFile.delete();
11425             }
11426
11427             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
11428                 resourceFile.delete();
11429             }
11430
11431             return true;
11432         }
11433
11434         void cleanUpResourcesLI() {
11435             // Try enumerating all code paths before deleting
11436             List<String> allCodePaths = Collections.EMPTY_LIST;
11437             if (codeFile != null && codeFile.exists()) {
11438                 try {
11439                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11440                     allCodePaths = pkg.getAllCodePaths();
11441                 } catch (PackageParserException e) {
11442                     // Ignored; we tried our best
11443                 }
11444             }
11445
11446             cleanUp();
11447             removeDexFiles(allCodePaths, instructionSets);
11448         }
11449
11450         boolean doPostDeleteLI(boolean delete) {
11451             // XXX err, shouldn't we respect the delete flag?
11452             cleanUpResourcesLI();
11453             return true;
11454         }
11455     }
11456
11457     private boolean isAsecExternal(String cid) {
11458         final String asecPath = PackageHelper.getSdFilesystem(cid);
11459         return !asecPath.startsWith(mAsecInternalPath);
11460     }
11461
11462     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
11463             PackageManagerException {
11464         if (copyRet < 0) {
11465             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
11466                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
11467                 throw new PackageManagerException(copyRet, message);
11468             }
11469         }
11470     }
11471
11472     /**
11473      * Extract the MountService "container ID" from the full code path of an
11474      * .apk.
11475      */
11476     static String cidFromCodePath(String fullCodePath) {
11477         int eidx = fullCodePath.lastIndexOf("/");
11478         String subStr1 = fullCodePath.substring(0, eidx);
11479         int sidx = subStr1.lastIndexOf("/");
11480         return subStr1.substring(sidx+1, eidx);
11481     }
11482
11483     /**
11484      * Logic to handle installation of ASEC applications, including copying and
11485      * renaming logic.
11486      */
11487     class AsecInstallArgs extends InstallArgs {
11488         static final String RES_FILE_NAME = "pkg.apk";
11489         static final String PUBLIC_RES_FILE_NAME = "res.zip";
11490
11491         String cid;
11492         String packagePath;
11493         String resourcePath;
11494
11495         /** New install */
11496         AsecInstallArgs(InstallParams params) {
11497             super(params.origin, params.move, params.observer, params.installFlags,
11498                     params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
11499                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11500                     params.grantedRuntimePermissions);
11501         }
11502
11503         /** Existing install */
11504         AsecInstallArgs(String fullCodePath, String[] instructionSets,
11505                         boolean isExternal, boolean isForwardLocked) {
11506             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
11507                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
11508                     instructionSets, null, null);
11509             // Hackily pretend we're still looking at a full code path
11510             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
11511                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
11512             }
11513
11514             // Extract cid from fullCodePath
11515             int eidx = fullCodePath.lastIndexOf("/");
11516             String subStr1 = fullCodePath.substring(0, eidx);
11517             int sidx = subStr1.lastIndexOf("/");
11518             cid = subStr1.substring(sidx+1, eidx);
11519             setMountPath(subStr1);
11520         }
11521
11522         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
11523             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
11524                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
11525                     instructionSets, null, null);
11526             this.cid = cid;
11527             setMountPath(PackageHelper.getSdDir(cid));
11528         }
11529
11530         void createCopyFile() {
11531             cid = mInstallerService.allocateExternalStageCidLegacy();
11532         }
11533
11534         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11535             if (origin.staged) {
11536                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
11537                 cid = origin.cid;
11538                 setMountPath(PackageHelper.getSdDir(cid));
11539                 return PackageManager.INSTALL_SUCCEEDED;
11540             }
11541
11542             if (temp) {
11543                 createCopyFile();
11544             } else {
11545                 /*
11546                  * Pre-emptively destroy the container since it's destroyed if
11547                  * copying fails due to it existing anyway.
11548                  */
11549                 PackageHelper.destroySdDir(cid);
11550             }
11551
11552             final String newMountPath = imcs.copyPackageToContainer(
11553                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
11554                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
11555
11556             if (newMountPath != null) {
11557                 setMountPath(newMountPath);
11558                 return PackageManager.INSTALL_SUCCEEDED;
11559             } else {
11560                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11561             }
11562         }
11563
11564         @Override
11565         String getCodePath() {
11566             return packagePath;
11567         }
11568
11569         @Override
11570         String getResourcePath() {
11571             return resourcePath;
11572         }
11573
11574         int doPreInstall(int status) {
11575             if (status != PackageManager.INSTALL_SUCCEEDED) {
11576                 // Destroy container
11577                 PackageHelper.destroySdDir(cid);
11578             } else {
11579                 boolean mounted = PackageHelper.isContainerMounted(cid);
11580                 if (!mounted) {
11581                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
11582                             Process.SYSTEM_UID);
11583                     if (newMountPath != null) {
11584                         setMountPath(newMountPath);
11585                     } else {
11586                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11587                     }
11588                 }
11589             }
11590             return status;
11591         }
11592
11593         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11594             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
11595             String newMountPath = null;
11596             if (PackageHelper.isContainerMounted(cid)) {
11597                 // Unmount the container
11598                 if (!PackageHelper.unMountSdDir(cid)) {
11599                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
11600                     return false;
11601                 }
11602             }
11603             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11604                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
11605                         " which might be stale. Will try to clean up.");
11606                 // Clean up the stale container and proceed to recreate.
11607                 if (!PackageHelper.destroySdDir(newCacheId)) {
11608                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
11609                     return false;
11610                 }
11611                 // Successfully cleaned up stale container. Try to rename again.
11612                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11613                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
11614                             + " inspite of cleaning it up.");
11615                     return false;
11616                 }
11617             }
11618             if (!PackageHelper.isContainerMounted(newCacheId)) {
11619                 Slog.w(TAG, "Mounting container " + newCacheId);
11620                 newMountPath = PackageHelper.mountSdDir(newCacheId,
11621                         getEncryptKey(), Process.SYSTEM_UID);
11622             } else {
11623                 newMountPath = PackageHelper.getSdDir(newCacheId);
11624             }
11625             if (newMountPath == null) {
11626                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
11627                 return false;
11628             }
11629             Log.i(TAG, "Succesfully renamed " + cid +
11630                     " to " + newCacheId +
11631                     " at new path: " + newMountPath);
11632             cid = newCacheId;
11633
11634             final File beforeCodeFile = new File(packagePath);
11635             setMountPath(newMountPath);
11636             final File afterCodeFile = new File(packagePath);
11637
11638             // Reflect the rename in scanned details
11639             pkg.codePath = afterCodeFile.getAbsolutePath();
11640             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11641                     pkg.baseCodePath);
11642             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11643                     pkg.splitCodePaths);
11644
11645             // Reflect the rename in app info
11646             pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11647             pkg.applicationInfo.setCodePath(pkg.codePath);
11648             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11649             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11650             pkg.applicationInfo.setResourcePath(pkg.codePath);
11651             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11652             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11653
11654             return true;
11655         }
11656
11657         private void setMountPath(String mountPath) {
11658             final File mountFile = new File(mountPath);
11659
11660             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
11661             if (monolithicFile.exists()) {
11662                 packagePath = monolithicFile.getAbsolutePath();
11663                 if (isFwdLocked()) {
11664                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
11665                 } else {
11666                     resourcePath = packagePath;
11667                 }
11668             } else {
11669                 packagePath = mountFile.getAbsolutePath();
11670                 resourcePath = packagePath;
11671             }
11672         }
11673
11674         int doPostInstall(int status, int uid) {
11675             if (status != PackageManager.INSTALL_SUCCEEDED) {
11676                 cleanUp();
11677             } else {
11678                 final int groupOwner;
11679                 final String protectedFile;
11680                 if (isFwdLocked()) {
11681                     groupOwner = UserHandle.getSharedAppGid(uid);
11682                     protectedFile = RES_FILE_NAME;
11683                 } else {
11684                     groupOwner = -1;
11685                     protectedFile = null;
11686                 }
11687
11688                 if (uid < Process.FIRST_APPLICATION_UID
11689                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
11690                     Slog.e(TAG, "Failed to finalize " + cid);
11691                     PackageHelper.destroySdDir(cid);
11692                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11693                 }
11694
11695                 boolean mounted = PackageHelper.isContainerMounted(cid);
11696                 if (!mounted) {
11697                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
11698                 }
11699             }
11700             return status;
11701         }
11702
11703         private void cleanUp() {
11704             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
11705
11706             // Destroy secure container
11707             PackageHelper.destroySdDir(cid);
11708         }
11709
11710         private List<String> getAllCodePaths() {
11711             final File codeFile = new File(getCodePath());
11712             if (codeFile != null && codeFile.exists()) {
11713                 try {
11714                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11715                     return pkg.getAllCodePaths();
11716                 } catch (PackageParserException e) {
11717                     // Ignored; we tried our best
11718                 }
11719             }
11720             return Collections.EMPTY_LIST;
11721         }
11722
11723         void cleanUpResourcesLI() {
11724             // Enumerate all code paths before deleting
11725             cleanUpResourcesLI(getAllCodePaths());
11726         }
11727
11728         private void cleanUpResourcesLI(List<String> allCodePaths) {
11729             cleanUp();
11730             removeDexFiles(allCodePaths, instructionSets);
11731         }
11732
11733         String getPackageName() {
11734             return getAsecPackageName(cid);
11735         }
11736
11737         boolean doPostDeleteLI(boolean delete) {
11738             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
11739             final List<String> allCodePaths = getAllCodePaths();
11740             boolean mounted = PackageHelper.isContainerMounted(cid);
11741             if (mounted) {
11742                 // Unmount first
11743                 if (PackageHelper.unMountSdDir(cid)) {
11744                     mounted = false;
11745                 }
11746             }
11747             if (!mounted && delete) {
11748                 cleanUpResourcesLI(allCodePaths);
11749             }
11750             return !mounted;
11751         }
11752
11753         @Override
11754         int doPreCopy() {
11755             if (isFwdLocked()) {
11756                 if (!PackageHelper.fixSdPermissions(cid,
11757                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
11758                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11759                 }
11760             }
11761
11762             return PackageManager.INSTALL_SUCCEEDED;
11763         }
11764
11765         @Override
11766         int doPostCopy(int uid) {
11767             if (isFwdLocked()) {
11768                 if (uid < Process.FIRST_APPLICATION_UID
11769                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
11770                                 RES_FILE_NAME)) {
11771                     Slog.e(TAG, "Failed to finalize " + cid);
11772                     PackageHelper.destroySdDir(cid);
11773                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11774                 }
11775             }
11776
11777             return PackageManager.INSTALL_SUCCEEDED;
11778         }
11779     }
11780
11781     /**
11782      * Logic to handle movement of existing installed applications.
11783      */
11784     class MoveInstallArgs extends InstallArgs {
11785         private File codeFile;
11786         private File resourceFile;
11787
11788         /** New install */
11789         MoveInstallArgs(InstallParams params) {
11790             super(params.origin, params.move, params.observer, params.installFlags,
11791                     params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
11792                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11793                     params.grantedRuntimePermissions);
11794         }
11795
11796         int copyApk(IMediaContainerService imcs, boolean temp) {
11797             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
11798                     + move.fromUuid + " to " + move.toUuid);
11799             synchronized (mInstaller) {
11800                 if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName,
11801                         move.dataAppName, move.appId, move.seinfo) != 0) {
11802                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11803                 }
11804             }
11805
11806             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
11807             resourceFile = codeFile;
11808             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
11809
11810             return PackageManager.INSTALL_SUCCEEDED;
11811         }
11812
11813         int doPreInstall(int status) {
11814             if (status != PackageManager.INSTALL_SUCCEEDED) {
11815                 cleanUp(move.toUuid);
11816             }
11817             return status;
11818         }
11819
11820         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11821             if (status != PackageManager.INSTALL_SUCCEEDED) {
11822                 cleanUp(move.toUuid);
11823                 return false;
11824             }
11825
11826             // Reflect the move in app info
11827             pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11828             pkg.applicationInfo.setCodePath(pkg.codePath);
11829             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11830             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11831             pkg.applicationInfo.setResourcePath(pkg.codePath);
11832             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11833             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11834
11835             return true;
11836         }
11837
11838         int doPostInstall(int status, int uid) {
11839             if (status == PackageManager.INSTALL_SUCCEEDED) {
11840                 cleanUp(move.fromUuid);
11841             } else {
11842                 cleanUp(move.toUuid);
11843             }
11844             return status;
11845         }
11846
11847         @Override
11848         String getCodePath() {
11849             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11850         }
11851
11852         @Override
11853         String getResourcePath() {
11854             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11855         }
11856
11857         private boolean cleanUp(String volumeUuid) {
11858             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
11859                     move.dataAppName);
11860             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
11861             synchronized (mInstallLock) {
11862                 // Clean up both app data and code
11863                 removeDataDirsLI(volumeUuid, move.packageName);
11864                 if (codeFile.isDirectory()) {
11865                     mInstaller.rmPackageDir(codeFile.getAbsolutePath());
11866                 } else {
11867                     codeFile.delete();
11868                 }
11869             }
11870             return true;
11871         }
11872
11873         void cleanUpResourcesLI() {
11874             throw new UnsupportedOperationException();
11875         }
11876
11877         boolean doPostDeleteLI(boolean delete) {
11878             throw new UnsupportedOperationException();
11879         }
11880     }
11881
11882     static String getAsecPackageName(String packageCid) {
11883         int idx = packageCid.lastIndexOf("-");
11884         if (idx == -1) {
11885             return packageCid;
11886         }
11887         return packageCid.substring(0, idx);
11888     }
11889
11890     // Utility method used to create code paths based on package name and available index.
11891     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
11892         String idxStr = "";
11893         int idx = 1;
11894         // Fall back to default value of idx=1 if prefix is not
11895         // part of oldCodePath
11896         if (oldCodePath != null) {
11897             String subStr = oldCodePath;
11898             // Drop the suffix right away
11899             if (suffix != null && subStr.endsWith(suffix)) {
11900                 subStr = subStr.substring(0, subStr.length() - suffix.length());
11901             }
11902             // If oldCodePath already contains prefix find out the
11903             // ending index to either increment or decrement.
11904             int sidx = subStr.lastIndexOf(prefix);
11905             if (sidx != -1) {
11906                 subStr = subStr.substring(sidx + prefix.length());
11907                 if (subStr != null) {
11908                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
11909                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
11910                     }
11911                     try {
11912                         idx = Integer.parseInt(subStr);
11913                         if (idx <= 1) {
11914                             idx++;
11915                         } else {
11916                             idx--;
11917                         }
11918                     } catch(NumberFormatException e) {
11919                     }
11920                 }
11921             }
11922         }
11923         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
11924         return prefix + idxStr;
11925     }
11926
11927     private File getNextCodePath(File targetDir, String packageName) {
11928         int suffix = 1;
11929         File result;
11930         do {
11931             result = new File(targetDir, packageName + "-" + suffix);
11932             suffix++;
11933         } while (result.exists());
11934         return result;
11935     }
11936
11937     // Utility method that returns the relative package path with respect
11938     // to the installation directory. Like say for /data/data/com.test-1.apk
11939     // string com.test-1 is returned.
11940     static String deriveCodePathName(String codePath) {
11941         if (codePath == null) {
11942             return null;
11943         }
11944         final File codeFile = new File(codePath);
11945         final String name = codeFile.getName();
11946         if (codeFile.isDirectory()) {
11947             return name;
11948         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
11949             final int lastDot = name.lastIndexOf('.');
11950             return name.substring(0, lastDot);
11951         } else {
11952             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
11953             return null;
11954         }
11955     }
11956
11957     class PackageInstalledInfo {
11958         String name;
11959         int uid;
11960         // The set of users that originally had this package installed.
11961         int[] origUsers;
11962         // The set of users that now have this package installed.
11963         int[] newUsers;
11964         PackageParser.Package pkg;
11965         int returnCode;
11966         String returnMsg;
11967         PackageRemovedInfo removedInfo;
11968
11969         public void setError(int code, String msg) {
11970             returnCode = code;
11971             returnMsg = msg;
11972             Slog.w(TAG, msg);
11973         }
11974
11975         public void setError(String msg, PackageParserException e) {
11976             returnCode = e.error;
11977             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
11978             Slog.w(TAG, msg, e);
11979         }
11980
11981         public void setError(String msg, PackageManagerException e) {
11982             returnCode = e.error;
11983             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
11984             Slog.w(TAG, msg, e);
11985         }
11986
11987         // In some error cases we want to convey more info back to the observer
11988         String origPackage;
11989         String origPermission;
11990     }
11991
11992     /*
11993      * Install a non-existing package.
11994      */
11995     private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
11996             UserHandle user, String installerPackageName, String volumeUuid,
11997             PackageInstalledInfo res) {
11998         // Remember this for later, in case we need to rollback this install
11999         String pkgName = pkg.packageName;
12000
12001         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
12002         final boolean dataDirExists = Environment
12003                 .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_OWNER, pkgName).exists();
12004         synchronized(mPackages) {
12005             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
12006                 // A package with the same name is already installed, though
12007                 // it has been renamed to an older name.  The package we
12008                 // are trying to install should be installed as an update to
12009                 // the existing one, but that has not been requested, so bail.
12010                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12011                         + " without first uninstalling package running as "
12012                         + mSettings.mRenamedPackages.get(pkgName));
12013                 return;
12014             }
12015             if (mPackages.containsKey(pkgName)) {
12016                 // Don't allow installation over an existing package with the same name.
12017                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12018                         + " without first uninstalling.");
12019                 return;
12020             }
12021         }
12022
12023         try {
12024             PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
12025                     System.currentTimeMillis(), user);
12026
12027             updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
12028             // delete the partially installed application. the data directory will have to be
12029             // restored if it was already existing
12030             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12031                 // remove package from internal structures.  Note that we want deletePackageX to
12032                 // delete the package data and cache directories that it created in
12033                 // scanPackageLocked, unless those directories existed before we even tried to
12034                 // install.
12035                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
12036                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
12037                                 res.removedInfo, true);
12038             }
12039
12040         } catch (PackageManagerException e) {
12041             res.setError("Package couldn't be installed in " + pkg.codePath, e);
12042         }
12043     }
12044
12045     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
12046         // Can't rotate keys during boot or if sharedUser.
12047         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
12048                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
12049             return false;
12050         }
12051         // app is using upgradeKeySets; make sure all are valid
12052         KeySetManagerService ksms = mSettings.mKeySetManagerService;
12053         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
12054         for (int i = 0; i < upgradeKeySets.length; i++) {
12055             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
12056                 Slog.wtf(TAG, "Package "
12057                          + (oldPs.name != null ? oldPs.name : "<null>")
12058                          + " contains upgrade-key-set reference to unknown key-set: "
12059                          + upgradeKeySets[i]
12060                          + " reverting to signatures check.");
12061                 return false;
12062             }
12063         }
12064         return true;
12065     }
12066
12067     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
12068         // Upgrade keysets are being used.  Determine if new package has a superset of the
12069         // required keys.
12070         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
12071         KeySetManagerService ksms = mSettings.mKeySetManagerService;
12072         for (int i = 0; i < upgradeKeySets.length; i++) {
12073             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
12074             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
12075                 return true;
12076             }
12077         }
12078         return false;
12079     }
12080
12081     private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12082             UserHandle user, String installerPackageName, String volumeUuid,
12083             PackageInstalledInfo res) {
12084         final PackageParser.Package oldPackage;
12085         final String pkgName = pkg.packageName;
12086         final int[] allUsers;
12087         final boolean[] perUserInstalled;
12088
12089         // First find the old package info and check signatures
12090         synchronized(mPackages) {
12091             oldPackage = mPackages.get(pkgName);
12092             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
12093             final PackageSetting ps = mSettings.mPackages.get(pkgName);
12094             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12095                 if(!checkUpgradeKeySetLP(ps, pkg)) {
12096                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12097                             "New package not signed by keys specified by upgrade-keysets: "
12098                             + pkgName);
12099                     return;
12100                 }
12101             } else {
12102                 // default to original signature matching
12103                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
12104                     != PackageManager.SIGNATURE_MATCH) {
12105                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12106                             "New package has a different signature: " + pkgName);
12107                     return;
12108                 }
12109             }
12110
12111             // In case of rollback, remember per-user/profile install state
12112             allUsers = sUserManager.getUserIds();
12113             perUserInstalled = new boolean[allUsers.length];
12114             for (int i = 0; i < allUsers.length; i++) {
12115                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
12116             }
12117         }
12118
12119         boolean sysPkg = (isSystemApp(oldPackage));
12120         if (sysPkg) {
12121             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12122                     user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12123         } else {
12124             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12125                     user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12126         }
12127     }
12128
12129     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
12130             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12131             int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12132             String volumeUuid, PackageInstalledInfo res) {
12133         String pkgName = deletedPackage.packageName;
12134         boolean deletedPkg = true;
12135         boolean updatedSettings = false;
12136
12137         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
12138                 + deletedPackage);
12139         long origUpdateTime;
12140         if (pkg.mExtras != null) {
12141             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
12142         } else {
12143             origUpdateTime = 0;
12144         }
12145
12146         // First delete the existing package while retaining the data directory
12147         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
12148                 res.removedInfo, true)) {
12149             // If the existing package wasn't successfully deleted
12150             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
12151             deletedPkg = false;
12152         } else {
12153             // Successfully deleted the old package; proceed with replace.
12154
12155             // If deleted package lived in a container, give users a chance to
12156             // relinquish resources before killing.
12157             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
12158                 if (DEBUG_INSTALL) {
12159                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
12160                 }
12161                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
12162                 final ArrayList<String> pkgList = new ArrayList<String>(1);
12163                 pkgList.add(deletedPackage.applicationInfo.packageName);
12164                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
12165             }
12166
12167             deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
12168             try {
12169                 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
12170                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
12171                 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12172                         perUserInstalled, res, user);
12173                 updatedSettings = true;
12174             } catch (PackageManagerException e) {
12175                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
12176             }
12177         }
12178
12179         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12180             // remove package from internal structures.  Note that we want deletePackageX to
12181             // delete the package data and cache directories that it created in
12182             // scanPackageLocked, unless those directories existed before we even tried to
12183             // install.
12184             if(updatedSettings) {
12185                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
12186                 deletePackageLI(
12187                         pkgName, null, true, allUsers, perUserInstalled,
12188                         PackageManager.DELETE_KEEP_DATA,
12189                                 res.removedInfo, true);
12190             }
12191             // Since we failed to install the new package we need to restore the old
12192             // package that we deleted.
12193             if (deletedPkg) {
12194                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
12195                 File restoreFile = new File(deletedPackage.codePath);
12196                 // Parse old package
12197                 boolean oldExternal = isExternal(deletedPackage);
12198                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
12199                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
12200                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
12201                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
12202                 try {
12203                     scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
12204                 } catch (PackageManagerException e) {
12205                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
12206                             + e.getMessage());
12207                     return;
12208                 }
12209                 // Restore of old package succeeded. Update permissions.
12210                 // writer
12211                 synchronized (mPackages) {
12212                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
12213                             UPDATE_PERMISSIONS_ALL);
12214                     // can downgrade to reader
12215                     mSettings.writeLPr();
12216                 }
12217                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
12218             }
12219         }
12220     }
12221
12222     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
12223             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12224             int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12225             String volumeUuid, PackageInstalledInfo res) {
12226         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
12227                 + ", old=" + deletedPackage);
12228         boolean disabledSystem = false;
12229         boolean updatedSettings = false;
12230         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
12231         if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
12232                 != 0) {
12233             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
12234         }
12235         String packageName = deletedPackage.packageName;
12236         if (packageName == null) {
12237             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12238                     "Attempt to delete null packageName.");
12239             return;
12240         }
12241         PackageParser.Package oldPkg;
12242         PackageSetting oldPkgSetting;
12243         // reader
12244         synchronized (mPackages) {
12245             oldPkg = mPackages.get(packageName);
12246             oldPkgSetting = mSettings.mPackages.get(packageName);
12247             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
12248                     (oldPkgSetting == null)) {
12249                 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12250                         "Couldn't find package:" + packageName + " information");
12251                 return;
12252             }
12253         }
12254
12255         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
12256
12257         res.removedInfo.uid = oldPkg.applicationInfo.uid;
12258         res.removedInfo.removedPackage = packageName;
12259         // Remove existing system package
12260         removePackageLI(oldPkgSetting, true);
12261         // writer
12262         synchronized (mPackages) {
12263             disabledSystem = mSettings.disableSystemPackageLPw(packageName);
12264             if (!disabledSystem && deletedPackage != null) {
12265                 // We didn't need to disable the .apk as a current system package,
12266                 // which means we are replacing another update that is already
12267                 // installed.  We need to make sure to delete the older one's .apk.
12268                 res.removedInfo.args = createInstallArgsForExisting(0,
12269                         deletedPackage.applicationInfo.getCodePath(),
12270                         deletedPackage.applicationInfo.getResourcePath(),
12271                         getAppDexInstructionSets(deletedPackage.applicationInfo));
12272             } else {
12273                 res.removedInfo.args = null;
12274             }
12275         }
12276
12277         // Successfully disabled the old package. Now proceed with re-installation
12278         deleteCodeCacheDirsLI(pkg.volumeUuid, packageName);
12279
12280         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12281         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
12282
12283         PackageParser.Package newPackage = null;
12284         try {
12285             newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
12286             if (newPackage.mExtras != null) {
12287                 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
12288                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
12289                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
12290
12291                 // is the update attempting to change shared user? that isn't going to work...
12292                 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
12293                     res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
12294                             "Forbidding shared user change from " + oldPkgSetting.sharedUser
12295                             + " to " + newPkgSetting.sharedUser);
12296                     updatedSettings = true;
12297                 }
12298             }
12299
12300             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12301                 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12302                         perUserInstalled, res, user);
12303                 updatedSettings = true;
12304             }
12305
12306         } catch (PackageManagerException e) {
12307             res.setError("Package couldn't be installed in " + pkg.codePath, e);
12308         }
12309
12310         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12311             // Re installation failed. Restore old information
12312             // Remove new pkg information
12313             if (newPackage != null) {
12314                 removeInstalledPackageLI(newPackage, true);
12315             }
12316             // Add back the old system package
12317             try {
12318                 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
12319             } catch (PackageManagerException e) {
12320                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
12321             }
12322             // Restore the old system information in Settings
12323             synchronized (mPackages) {
12324                 if (disabledSystem) {
12325                     mSettings.enableSystemPackageLPw(packageName);
12326                 }
12327                 if (updatedSettings) {
12328                     mSettings.setInstallerPackageName(packageName,
12329                             oldPkgSetting.installerPackageName);
12330                 }
12331                 mSettings.writeLPr();
12332             }
12333         }
12334     }
12335
12336     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
12337         // Collect all used permissions in the UID
12338         ArraySet<String> usedPermissions = new ArraySet<>();
12339         final int packageCount = su.packages.size();
12340         for (int i = 0; i < packageCount; i++) {
12341             PackageSetting ps = su.packages.valueAt(i);
12342             if (ps.pkg == null) {
12343                 continue;
12344             }
12345             final int requestedPermCount = ps.pkg.requestedPermissions.size();
12346             for (int j = 0; j < requestedPermCount; j++) {
12347                 String permission = ps.pkg.requestedPermissions.get(j);
12348                 BasePermission bp = mSettings.mPermissions.get(permission);
12349                 if (bp != null) {
12350                     usedPermissions.add(permission);
12351                 }
12352             }
12353         }
12354
12355         PermissionsState permissionsState = su.getPermissionsState();
12356         // Prune install permissions
12357         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
12358         final int installPermCount = installPermStates.size();
12359         for (int i = installPermCount - 1; i >= 0;  i--) {
12360             PermissionState permissionState = installPermStates.get(i);
12361             if (!usedPermissions.contains(permissionState.getName())) {
12362                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12363                 if (bp != null) {
12364                     permissionsState.revokeInstallPermission(bp);
12365                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12366                             PackageManager.MASK_PERMISSION_FLAGS, 0);
12367                 }
12368             }
12369         }
12370
12371         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
12372
12373         // Prune runtime permissions
12374         for (int userId : allUserIds) {
12375             List<PermissionState> runtimePermStates = permissionsState
12376                     .getRuntimePermissionStates(userId);
12377             final int runtimePermCount = runtimePermStates.size();
12378             for (int i = runtimePermCount - 1; i >= 0; i--) {
12379                 PermissionState permissionState = runtimePermStates.get(i);
12380                 if (!usedPermissions.contains(permissionState.getName())) {
12381                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12382                     if (bp != null) {
12383                         permissionsState.revokeRuntimePermission(bp, userId);
12384                         permissionsState.updatePermissionFlags(bp, userId,
12385                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
12386                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
12387                                 runtimePermissionChangedUserIds, userId);
12388                     }
12389                 }
12390             }
12391         }
12392
12393         return runtimePermissionChangedUserIds;
12394     }
12395
12396     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
12397             String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
12398             UserHandle user) {
12399         String pkgName = newPackage.packageName;
12400         synchronized (mPackages) {
12401             //write settings. the installStatus will be incomplete at this stage.
12402             //note that the new package setting would have already been
12403             //added to mPackages. It hasn't been persisted yet.
12404             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
12405             mSettings.writeLPr();
12406         }
12407
12408         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
12409
12410         synchronized (mPackages) {
12411             updatePermissionsLPw(newPackage.packageName, newPackage,
12412                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
12413                             ? UPDATE_PERMISSIONS_ALL : 0));
12414             // For system-bundled packages, we assume that installing an upgraded version
12415             // of the package implies that the user actually wants to run that new code,
12416             // so we enable the package.
12417             PackageSetting ps = mSettings.mPackages.get(pkgName);
12418             if (ps != null) {
12419                 if (isSystemApp(newPackage)) {
12420                     // NB: implicit assumption that system package upgrades apply to all users
12421                     if (DEBUG_INSTALL) {
12422                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
12423                     }
12424                     if (res.origUsers != null) {
12425                         for (int userHandle : res.origUsers) {
12426                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
12427                                     userHandle, installerPackageName);
12428                         }
12429                     }
12430                     // Also convey the prior install/uninstall state
12431                     if (allUsers != null && perUserInstalled != null) {
12432                         for (int i = 0; i < allUsers.length; i++) {
12433                             if (DEBUG_INSTALL) {
12434                                 Slog.d(TAG, "    user " + allUsers[i]
12435                                         + " => " + perUserInstalled[i]);
12436                             }
12437                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
12438                         }
12439                         // these install state changes will be persisted in the
12440                         // upcoming call to mSettings.writeLPr().
12441                     }
12442                 }
12443                 // It's implied that when a user requests installation, they want the app to be
12444                 // installed and enabled.
12445                 int userId = user.getIdentifier();
12446                 if (userId != UserHandle.USER_ALL) {
12447                     ps.setInstalled(true, userId);
12448                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
12449                 }
12450             }
12451             res.name = pkgName;
12452             res.uid = newPackage.applicationInfo.uid;
12453             res.pkg = newPackage;
12454             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
12455             mSettings.setInstallerPackageName(pkgName, installerPackageName);
12456             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12457             //to update install status
12458             mSettings.writeLPr();
12459         }
12460     }
12461
12462     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
12463         final int installFlags = args.installFlags;
12464         final String installerPackageName = args.installerPackageName;
12465         final String volumeUuid = args.volumeUuid;
12466         final File tmpPackageFile = new File(args.getCodePath());
12467         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
12468         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
12469                 || (args.volumeUuid != null));
12470         boolean replace = false;
12471         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
12472         if (args.move != null) {
12473             // moving a complete application; perfom an initial scan on the new install location
12474             scanFlags |= SCAN_INITIAL;
12475         }
12476         // Result object to be returned
12477         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12478
12479         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
12480         // Retrieve PackageSettings and parse package
12481         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
12482                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
12483                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
12484         PackageParser pp = new PackageParser();
12485         pp.setSeparateProcesses(mSeparateProcesses);
12486         pp.setDisplayMetrics(mMetrics);
12487
12488         final PackageParser.Package pkg;
12489         try {
12490             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
12491         } catch (PackageParserException e) {
12492             res.setError("Failed parse during installPackageLI", e);
12493             return;
12494         }
12495
12496         // Mark that we have an install time CPU ABI override.
12497         pkg.cpuAbiOverride = args.abiOverride;
12498
12499         String pkgName = res.name = pkg.packageName;
12500         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
12501             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
12502                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
12503                 return;
12504             }
12505         }
12506
12507         try {
12508             pp.collectCertificates(pkg, parseFlags);
12509             pp.collectManifestDigest(pkg);
12510         } catch (PackageParserException e) {
12511             res.setError("Failed collect during installPackageLI", e);
12512             return;
12513         }
12514
12515         /* If the installer passed in a manifest digest, compare it now. */
12516         if (args.manifestDigest != null) {
12517             if (DEBUG_INSTALL) {
12518                 final String parsedManifest = pkg.manifestDigest == null ? "null"
12519                         : pkg.manifestDigest.toString();
12520                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
12521                         + parsedManifest);
12522             }
12523
12524             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
12525                 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
12526                 return;
12527             }
12528         } else if (DEBUG_INSTALL) {
12529             final String parsedManifest = pkg.manifestDigest == null
12530                     ? "null" : pkg.manifestDigest.toString();
12531             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
12532         }
12533
12534         // Get rid of all references to package scan path via parser.
12535         pp = null;
12536         String oldCodePath = null;
12537         boolean systemApp = false;
12538         synchronized (mPackages) {
12539             // Check if installing already existing package
12540             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
12541                 String oldName = mSettings.mRenamedPackages.get(pkgName);
12542                 if (pkg.mOriginalPackages != null
12543                         && pkg.mOriginalPackages.contains(oldName)
12544                         && mPackages.containsKey(oldName)) {
12545                     // This package is derived from an original package,
12546                     // and this device has been updating from that original
12547                     // name.  We must continue using the original name, so
12548                     // rename the new package here.
12549                     pkg.setPackageName(oldName);
12550                     pkgName = pkg.packageName;
12551                     replace = true;
12552                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
12553                             + oldName + " pkgName=" + pkgName);
12554                 } else if (mPackages.containsKey(pkgName)) {
12555                     // This package, under its official name, already exists
12556                     // on the device; we should replace it.
12557                     replace = true;
12558                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
12559                 }
12560
12561                 // Prevent apps opting out from runtime permissions
12562                 if (replace) {
12563                     PackageParser.Package oldPackage = mPackages.get(pkgName);
12564                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
12565                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
12566                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
12567                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
12568                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
12569                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
12570                                         + " doesn't support runtime permissions but the old"
12571                                         + " target SDK " + oldTargetSdk + " does.");
12572                         return;
12573                     }
12574                 }
12575             }
12576
12577             PackageSetting ps = mSettings.mPackages.get(pkgName);
12578             if (ps != null) {
12579                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
12580
12581                 // Quick sanity check that we're signed correctly if updating;
12582                 // we'll check this again later when scanning, but we want to
12583                 // bail early here before tripping over redefined permissions.
12584                 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12585                     if (!checkUpgradeKeySetLP(ps, pkg)) {
12586                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
12587                                 + pkg.packageName + " upgrade keys do not match the "
12588                                 + "previously installed version");
12589                         return;
12590                     }
12591                 } else {
12592                     try {
12593                         verifySignaturesLP(ps, pkg);
12594                     } catch (PackageManagerException e) {
12595                         res.setError(e.error, e.getMessage());
12596                         return;
12597                     }
12598                 }
12599
12600                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
12601                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
12602                     systemApp = (ps.pkg.applicationInfo.flags &
12603                             ApplicationInfo.FLAG_SYSTEM) != 0;
12604                 }
12605                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
12606             }
12607
12608             // Check whether the newly-scanned package wants to define an already-defined perm
12609             int N = pkg.permissions.size();
12610             for (int i = N-1; i >= 0; i--) {
12611                 PackageParser.Permission perm = pkg.permissions.get(i);
12612                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
12613                 if (bp != null) {
12614                     // If the defining package is signed with our cert, it's okay.  This
12615                     // also includes the "updating the same package" case, of course.
12616                     // "updating same package" could also involve key-rotation.
12617                     final boolean sigsOk;
12618                     if (bp.sourcePackage.equals(pkg.packageName)
12619                             && (bp.packageSetting instanceof PackageSetting)
12620                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
12621                                     scanFlags))) {
12622                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
12623                     } else {
12624                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
12625                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
12626                     }
12627                     if (!sigsOk) {
12628                         // If the owning package is the system itself, we log but allow
12629                         // install to proceed; we fail the install on all other permission
12630                         // redefinitions.
12631                         if (!bp.sourcePackage.equals("android")) {
12632                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
12633                                     + pkg.packageName + " attempting to redeclare permission "
12634                                     + perm.info.name + " already owned by " + bp.sourcePackage);
12635                             res.origPermission = perm.info.name;
12636                             res.origPackage = bp.sourcePackage;
12637                             return;
12638                         } else {
12639                             Slog.w(TAG, "Package " + pkg.packageName
12640                                     + " attempting to redeclare system permission "
12641                                     + perm.info.name + "; ignoring new declaration");
12642                             pkg.permissions.remove(i);
12643                         }
12644                     }
12645                 }
12646             }
12647
12648         }
12649
12650         if (systemApp && onExternal) {
12651             // Disable updates to system apps on sdcard
12652             res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
12653                     "Cannot install updates to system apps on sdcard");
12654             return;
12655         }
12656
12657         if (args.move != null) {
12658             // We did an in-place move, so dex is ready to roll
12659             scanFlags |= SCAN_NO_DEX;
12660             scanFlags |= SCAN_MOVE;
12661
12662             synchronized (mPackages) {
12663                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
12664                 if (ps == null) {
12665                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
12666                             "Missing settings for moved package " + pkgName);
12667                 }
12668
12669                 // We moved the entire application as-is, so bring over the
12670                 // previously derived ABI information.
12671                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
12672                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
12673             }
12674
12675         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
12676             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
12677             scanFlags |= SCAN_NO_DEX;
12678
12679             try {
12680                 derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
12681                         true /* extract libs */);
12682             } catch (PackageManagerException pme) {
12683                 Slog.e(TAG, "Error deriving application ABI", pme);
12684                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
12685                 return;
12686             }
12687
12688             // Run dexopt before old package gets removed, to minimize time when app is unavailable
12689             int result = mPackageDexOptimizer
12690                     .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */,
12691                             false /* defer */, false /* inclDependencies */,
12692                             true /* boot complete */);
12693             if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
12694                 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
12695                 return;
12696             }
12697         }
12698
12699         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
12700             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
12701             return;
12702         }
12703
12704         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
12705
12706         if (replace) {
12707             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
12708                     installerPackageName, volumeUuid, res);
12709         } else {
12710             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
12711                     args.user, installerPackageName, volumeUuid, res);
12712         }
12713         synchronized (mPackages) {
12714             final PackageSetting ps = mSettings.mPackages.get(pkgName);
12715             if (ps != null) {
12716                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
12717             }
12718         }
12719     }
12720
12721     private void startIntentFilterVerifications(int userId, boolean replacing,
12722             PackageParser.Package pkg) {
12723         if (mIntentFilterVerifierComponent == null) {
12724             Slog.w(TAG, "No IntentFilter verification will not be done as "
12725                     + "there is no IntentFilterVerifier available!");
12726             return;
12727         }
12728
12729         final int verifierUid = getPackageUid(
12730                 mIntentFilterVerifierComponent.getPackageName(),
12731                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId);
12732
12733         mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
12734         final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
12735         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
12736         mHandler.sendMessage(msg);
12737     }
12738
12739     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
12740             PackageParser.Package pkg) {
12741         int size = pkg.activities.size();
12742         if (size == 0) {
12743             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12744                     "No activity, so no need to verify any IntentFilter!");
12745             return;
12746         }
12747
12748         final boolean hasDomainURLs = hasDomainURLs(pkg);
12749         if (!hasDomainURLs) {
12750             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12751                     "No domain URLs, so no need to verify any IntentFilter!");
12752             return;
12753         }
12754
12755         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
12756                 + " if any IntentFilter from the " + size
12757                 + " Activities needs verification ...");
12758
12759         int count = 0;
12760         final String packageName = pkg.packageName;
12761
12762         synchronized (mPackages) {
12763             // If this is a new install and we see that we've already run verification for this
12764             // package, we have nothing to do: it means the state was restored from backup.
12765             if (!replacing) {
12766                 IntentFilterVerificationInfo ivi =
12767                         mSettings.getIntentFilterVerificationLPr(packageName);
12768                 if (ivi != null) {
12769                     if (DEBUG_DOMAIN_VERIFICATION) {
12770                         Slog.i(TAG, "Package " + packageName+ " already verified: status="
12771                                 + ivi.getStatusString());
12772                     }
12773                     return;
12774                 }
12775             }
12776
12777             // If any filters need to be verified, then all need to be.
12778             boolean needToVerify = false;
12779             for (PackageParser.Activity a : pkg.activities) {
12780                 for (ActivityIntentInfo filter : a.intents) {
12781                     if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
12782                         if (DEBUG_DOMAIN_VERIFICATION) {
12783                             Slog.d(TAG, "Intent filter needs verification, so processing all filters");
12784                         }
12785                         needToVerify = true;
12786                         break;
12787                     }
12788                 }
12789             }
12790
12791             if (needToVerify) {
12792                 final int verificationId = mIntentFilterVerificationToken++;
12793                 for (PackageParser.Activity a : pkg.activities) {
12794                     for (ActivityIntentInfo filter : a.intents) {
12795                         if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
12796                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12797                                     "Verification needed for IntentFilter:" + filter.toString());
12798                             mIntentFilterVerifier.addOneIntentFilterVerification(
12799                                     verifierUid, userId, verificationId, filter, packageName);
12800                             count++;
12801                         }
12802                     }
12803                 }
12804             }
12805         }
12806
12807         if (count > 0) {
12808             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
12809                     + " IntentFilter verification" + (count > 1 ? "s" : "")
12810                     +  " for userId:" + userId);
12811             mIntentFilterVerifier.startVerifications(userId);
12812         } else {
12813             if (DEBUG_DOMAIN_VERIFICATION) {
12814                 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
12815             }
12816         }
12817     }
12818
12819     private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
12820         final ComponentName cn  = filter.activity.getComponentName();
12821         final String packageName = cn.getPackageName();
12822
12823         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
12824                 packageName);
12825         if (ivi == null) {
12826             return true;
12827         }
12828         int status = ivi.getStatus();
12829         switch (status) {
12830             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
12831             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
12832                 return true;
12833
12834             default:
12835                 // Nothing to do
12836                 return false;
12837         }
12838     }
12839
12840     private static boolean isMultiArch(PackageSetting ps) {
12841         return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
12842     }
12843
12844     private static boolean isMultiArch(ApplicationInfo info) {
12845         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
12846     }
12847
12848     private static boolean isExternal(PackageParser.Package pkg) {
12849         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12850     }
12851
12852     private static boolean isExternal(PackageSetting ps) {
12853         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12854     }
12855
12856     private static boolean isExternal(ApplicationInfo info) {
12857         return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12858     }
12859
12860     private static boolean isSystemApp(PackageParser.Package pkg) {
12861         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12862     }
12863
12864     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
12865         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
12866     }
12867
12868     private static boolean hasDomainURLs(PackageParser.Package pkg) {
12869         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
12870     }
12871
12872     private static boolean isSystemApp(PackageSetting ps) {
12873         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
12874     }
12875
12876     private static boolean isUpdatedSystemApp(PackageSetting ps) {
12877         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
12878     }
12879
12880     private int packageFlagsToInstallFlags(PackageSetting ps) {
12881         int installFlags = 0;
12882         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
12883             // This existing package was an external ASEC install when we have
12884             // the external flag without a UUID
12885             installFlags |= PackageManager.INSTALL_EXTERNAL;
12886         }
12887         if (ps.isForwardLocked()) {
12888             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
12889         }
12890         return installFlags;
12891     }
12892
12893     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
12894         if (isExternal(pkg)) {
12895             if (TextUtils.isEmpty(pkg.volumeUuid)) {
12896                 return StorageManager.UUID_PRIMARY_PHYSICAL;
12897             } else {
12898                 return pkg.volumeUuid;
12899             }
12900         } else {
12901             return StorageManager.UUID_PRIVATE_INTERNAL;
12902         }
12903     }
12904
12905     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
12906         if (isExternal(pkg)) {
12907             if (TextUtils.isEmpty(pkg.volumeUuid)) {
12908                 return mSettings.getExternalVersion();
12909             } else {
12910                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
12911             }
12912         } else {
12913             return mSettings.getInternalVersion();
12914         }
12915     }
12916
12917     private void deleteTempPackageFiles() {
12918         final FilenameFilter filter = new FilenameFilter() {
12919             public boolean accept(File dir, String name) {
12920                 return name.startsWith("vmdl") && name.endsWith(".tmp");
12921             }
12922         };
12923         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
12924             file.delete();
12925         }
12926     }
12927
12928     @Override
12929     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
12930             int flags) {
12931         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
12932                 flags);
12933     }
12934
12935     @Override
12936     public void deletePackage(final String packageName,
12937             final IPackageDeleteObserver2 observer, final int userId, final int flags) {
12938         mContext.enforceCallingOrSelfPermission(
12939                 android.Manifest.permission.DELETE_PACKAGES, null);
12940         Preconditions.checkNotNull(packageName);
12941         Preconditions.checkNotNull(observer);
12942         final int uid = Binder.getCallingUid();
12943         if (UserHandle.getUserId(uid) != userId) {
12944             mContext.enforceCallingPermission(
12945                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12946                     "deletePackage for user " + userId);
12947         }
12948         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
12949             try {
12950                 observer.onPackageDeleted(packageName,
12951                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
12952             } catch (RemoteException re) {
12953             }
12954             return;
12955         }
12956
12957         boolean uninstallBlocked = false;
12958         if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
12959             int[] users = sUserManager.getUserIds();
12960             for (int i = 0; i < users.length; ++i) {
12961                 if (getBlockUninstallForUser(packageName, users[i])) {
12962                     uninstallBlocked = true;
12963                     break;
12964                 }
12965             }
12966         } else {
12967             uninstallBlocked = getBlockUninstallForUser(packageName, userId);
12968         }
12969         if (uninstallBlocked) {
12970             try {
12971                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
12972                         null);
12973             } catch (RemoteException re) {
12974             }
12975             return;
12976         }
12977
12978         if (DEBUG_REMOVE) {
12979             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
12980         }
12981         // Queue up an async operation since the package deletion may take a little while.
12982         mHandler.post(new Runnable() {
12983             public void run() {
12984                 mHandler.removeCallbacks(this);
12985                 final int returnCode = deletePackageX(packageName, userId, flags);
12986                 if (observer != null) {
12987                     try {
12988                         observer.onPackageDeleted(packageName, returnCode, null);
12989                     } catch (RemoteException e) {
12990                         Log.i(TAG, "Observer no longer exists.");
12991                     } //end catch
12992                 } //end if
12993             } //end run
12994         });
12995     }
12996
12997     private boolean isPackageDeviceAdmin(String packageName, int userId) {
12998         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
12999                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13000         try {
13001             if (dpm != null) {
13002                 if (dpm.isDeviceOwner(packageName)) {
13003                     return true;
13004                 }
13005                 int[] users;
13006                 if (userId == UserHandle.USER_ALL) {
13007                     users = sUserManager.getUserIds();
13008                 } else {
13009                     users = new int[]{userId};
13010                 }
13011                 for (int i = 0; i < users.length; ++i) {
13012                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
13013                         return true;
13014                     }
13015                 }
13016             }
13017         } catch (RemoteException e) {
13018         }
13019         return false;
13020     }
13021
13022     /**
13023      *  This method is an internal method that could be get invoked either
13024      *  to delete an installed package or to clean up a failed installation.
13025      *  After deleting an installed package, a broadcast is sent to notify any
13026      *  listeners that the package has been installed. For cleaning up a failed
13027      *  installation, the broadcast is not necessary since the package's
13028      *  installation wouldn't have sent the initial broadcast either
13029      *  The key steps in deleting a package are
13030      *  deleting the package information in internal structures like mPackages,
13031      *  deleting the packages base directories through installd
13032      *  updating mSettings to reflect current status
13033      *  persisting settings for later use
13034      *  sending a broadcast if necessary
13035      */
13036     private int deletePackageX(String packageName, int userId, int flags) {
13037         final PackageRemovedInfo info = new PackageRemovedInfo();
13038         final boolean res;
13039
13040         final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
13041                 ? UserHandle.ALL : new UserHandle(userId);
13042
13043         if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
13044             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
13045             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
13046         }
13047
13048         boolean removedForAllUsers = false;
13049         boolean systemUpdate = false;
13050
13051         // for the uninstall-updates case and restricted profiles, remember the per-
13052         // userhandle installed state
13053         int[] allUsers;
13054         boolean[] perUserInstalled;
13055         synchronized (mPackages) {
13056             PackageSetting ps = mSettings.mPackages.get(packageName);
13057             allUsers = sUserManager.getUserIds();
13058             perUserInstalled = new boolean[allUsers.length];
13059             for (int i = 0; i < allUsers.length; i++) {
13060                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
13061             }
13062         }
13063
13064         synchronized (mInstallLock) {
13065             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
13066             res = deletePackageLI(packageName, removeForUser,
13067                     true, allUsers, perUserInstalled,
13068                     flags | REMOVE_CHATTY, info, true);
13069             systemUpdate = info.isRemovedPackageSystemUpdate;
13070             if (res && !systemUpdate && mPackages.get(packageName) == null) {
13071                 removedForAllUsers = true;
13072             }
13073             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
13074                     + " removedForAllUsers=" + removedForAllUsers);
13075         }
13076
13077         if (res) {
13078             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
13079
13080             // If the removed package was a system update, the old system package
13081             // was re-enabled; we need to broadcast this information
13082             if (systemUpdate) {
13083                 Bundle extras = new Bundle(1);
13084                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
13085                         ? info.removedAppId : info.uid);
13086                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
13087
13088                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13089                         extras, null, null, null);
13090                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
13091                         extras, null, null, null);
13092                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
13093                         null, packageName, null, null);
13094             }
13095         }
13096         // Force a gc here.
13097         Runtime.getRuntime().gc();
13098         // Delete the resources here after sending the broadcast to let
13099         // other processes clean up before deleting resources.
13100         if (info.args != null) {
13101             synchronized (mInstallLock) {
13102                 info.args.doPostDeleteLI(true);
13103             }
13104         }
13105
13106         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
13107     }
13108
13109     class PackageRemovedInfo {
13110         String removedPackage;
13111         int uid = -1;
13112         int removedAppId = -1;
13113         int[] removedUsers = null;
13114         boolean isRemovedPackageSystemUpdate = false;
13115         // Clean up resources deleted packages.
13116         InstallArgs args = null;
13117
13118         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
13119             Bundle extras = new Bundle(1);
13120             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
13121             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
13122             if (replacing) {
13123                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
13124             }
13125             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
13126             if (removedPackage != null) {
13127                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
13128                         extras, null, null, removedUsers);
13129                 if (fullRemove && !replacing) {
13130                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
13131                             extras, null, null, removedUsers);
13132                 }
13133             }
13134             if (removedAppId >= 0) {
13135                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
13136                         removedUsers);
13137             }
13138         }
13139     }
13140
13141     /*
13142      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
13143      * flag is not set, the data directory is removed as well.
13144      * make sure this flag is set for partially installed apps. If not its meaningless to
13145      * delete a partially installed application.
13146      */
13147     private void removePackageDataLI(PackageSetting ps,
13148             int[] allUserHandles, boolean[] perUserInstalled,
13149             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
13150         String packageName = ps.name;
13151         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
13152         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
13153         // Retrieve object to delete permissions for shared user later on
13154         final PackageSetting deletedPs;
13155         // reader
13156         synchronized (mPackages) {
13157             deletedPs = mSettings.mPackages.get(packageName);
13158             if (outInfo != null) {
13159                 outInfo.removedPackage = packageName;
13160                 outInfo.removedUsers = deletedPs != null
13161                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
13162                         : null;
13163             }
13164         }
13165         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13166             removeDataDirsLI(ps.volumeUuid, packageName);
13167             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
13168         }
13169         // writer
13170         synchronized (mPackages) {
13171             if (deletedPs != null) {
13172                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13173                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
13174                     clearDefaultBrowserIfNeeded(packageName);
13175                     if (outInfo != null) {
13176                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
13177                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
13178                     }
13179                     updatePermissionsLPw(deletedPs.name, null, 0);
13180                     if (deletedPs.sharedUser != null) {
13181                         // Remove permissions associated with package. Since runtime
13182                         // permissions are per user we have to kill the removed package
13183                         // or packages running under the shared user of the removed
13184                         // package if revoking the permissions requested only by the removed
13185                         // package is successful and this causes a change in gids.
13186                         for (int userId : UserManagerService.getInstance().getUserIds()) {
13187                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
13188                                     userId);
13189                             if (userIdToKill == UserHandle.USER_ALL
13190                                     || userIdToKill >= UserHandle.USER_OWNER) {
13191                                 // If gids changed for this user, kill all affected packages.
13192                                 mHandler.post(new Runnable() {
13193                                     @Override
13194                                     public void run() {
13195                                         // This has to happen with no lock held.
13196                                         killApplication(deletedPs.name, deletedPs.appId,
13197                                                 KILL_APP_REASON_GIDS_CHANGED);
13198                                     }
13199                                 });
13200                                 break;
13201                             }
13202                         }
13203                     }
13204                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
13205                 }
13206                 // make sure to preserve per-user disabled state if this removal was just
13207                 // a downgrade of a system app to the factory package
13208                 if (allUserHandles != null && perUserInstalled != null) {
13209                     if (DEBUG_REMOVE) {
13210                         Slog.d(TAG, "Propagating install state across downgrade");
13211                     }
13212                     for (int i = 0; i < allUserHandles.length; i++) {
13213                         if (DEBUG_REMOVE) {
13214                             Slog.d(TAG, "    user " + allUserHandles[i]
13215                                     + " => " + perUserInstalled[i]);
13216                         }
13217                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13218                     }
13219                 }
13220             }
13221             // can downgrade to reader
13222             if (writeSettings) {
13223                 // Save settings now
13224                 mSettings.writeLPr();
13225             }
13226         }
13227         if (outInfo != null) {
13228             // A user ID was deleted here. Go through all users and remove it
13229             // from KeyStore.
13230             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
13231         }
13232     }
13233
13234     static boolean locationIsPrivileged(File path) {
13235         try {
13236             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
13237                     .getCanonicalPath();
13238             return path.getCanonicalPath().startsWith(privilegedAppDir);
13239         } catch (IOException e) {
13240             Slog.e(TAG, "Unable to access code path " + path);
13241         }
13242         return false;
13243     }
13244
13245     /*
13246      * Tries to delete system package.
13247      */
13248     private boolean deleteSystemPackageLI(PackageSetting newPs,
13249             int[] allUserHandles, boolean[] perUserInstalled,
13250             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
13251         final boolean applyUserRestrictions
13252                 = (allUserHandles != null) && (perUserInstalled != null);
13253         PackageSetting disabledPs = null;
13254         // Confirm if the system package has been updated
13255         // An updated system app can be deleted. This will also have to restore
13256         // the system pkg from system partition
13257         // reader
13258         synchronized (mPackages) {
13259             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
13260         }
13261         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
13262                 + " disabledPs=" + disabledPs);
13263         if (disabledPs == null) {
13264             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
13265             return false;
13266         } else if (DEBUG_REMOVE) {
13267             Slog.d(TAG, "Deleting system pkg from data partition");
13268         }
13269         if (DEBUG_REMOVE) {
13270             if (applyUserRestrictions) {
13271                 Slog.d(TAG, "Remembering install states:");
13272                 for (int i = 0; i < allUserHandles.length; i++) {
13273                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
13274                 }
13275             }
13276         }
13277         // Delete the updated package
13278         outInfo.isRemovedPackageSystemUpdate = true;
13279         if (disabledPs.versionCode < newPs.versionCode) {
13280             // Delete data for downgrades
13281             flags &= ~PackageManager.DELETE_KEEP_DATA;
13282         } else {
13283             // Preserve data by setting flag
13284             flags |= PackageManager.DELETE_KEEP_DATA;
13285         }
13286         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
13287                 allUserHandles, perUserInstalled, outInfo, writeSettings);
13288         if (!ret) {
13289             return false;
13290         }
13291         // writer
13292         synchronized (mPackages) {
13293             // Reinstate the old system package
13294             mSettings.enableSystemPackageLPw(newPs.name);
13295             // Remove any native libraries from the upgraded package.
13296             NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
13297         }
13298         // Install the system package
13299         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
13300         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
13301         if (locationIsPrivileged(disabledPs.codePath)) {
13302             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
13303         }
13304
13305         final PackageParser.Package newPkg;
13306         try {
13307             newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
13308         } catch (PackageManagerException e) {
13309             Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
13310             return false;
13311         }
13312
13313         // writer
13314         synchronized (mPackages) {
13315             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
13316
13317             // Propagate the permissions state as we do not want to drop on the floor
13318             // runtime permissions. The update permissions method below will take
13319             // care of removing obsolete permissions and grant install permissions.
13320             ps.getPermissionsState().copyFrom(newPs.getPermissionsState());
13321             updatePermissionsLPw(newPkg.packageName, newPkg,
13322                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
13323
13324             if (applyUserRestrictions) {
13325                 if (DEBUG_REMOVE) {
13326                     Slog.d(TAG, "Propagating install state across reinstall");
13327                 }
13328                 for (int i = 0; i < allUserHandles.length; i++) {
13329                     if (DEBUG_REMOVE) {
13330                         Slog.d(TAG, "    user " + allUserHandles[i]
13331                                 + " => " + perUserInstalled[i]);
13332                     }
13333                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13334
13335                     mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false);
13336                 }
13337                 // Regardless of writeSettings we need to ensure that this restriction
13338                 // state propagation is persisted
13339                 mSettings.writeAllUsersPackageRestrictionsLPr();
13340             }
13341             // can downgrade to reader here
13342             if (writeSettings) {
13343                 mSettings.writeLPr();
13344             }
13345         }
13346         return true;
13347     }
13348
13349     private boolean deleteInstalledPackageLI(PackageSetting ps,
13350             boolean deleteCodeAndResources, int flags,
13351             int[] allUserHandles, boolean[] perUserInstalled,
13352             PackageRemovedInfo outInfo, boolean writeSettings) {
13353         if (outInfo != null) {
13354             outInfo.uid = ps.appId;
13355         }
13356
13357         // Delete package data from internal structures and also remove data if flag is set
13358         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
13359
13360         // Delete application code and resources
13361         if (deleteCodeAndResources && (outInfo != null)) {
13362             outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
13363                     ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
13364             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
13365         }
13366         return true;
13367     }
13368
13369     @Override
13370     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
13371             int userId) {
13372         mContext.enforceCallingOrSelfPermission(
13373                 android.Manifest.permission.DELETE_PACKAGES, null);
13374         synchronized (mPackages) {
13375             PackageSetting ps = mSettings.mPackages.get(packageName);
13376             if (ps == null) {
13377                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
13378                 return false;
13379             }
13380             if (!ps.getInstalled(userId)) {
13381                 // Can't block uninstall for an app that is not installed or enabled.
13382                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
13383                 return false;
13384             }
13385             ps.setBlockUninstall(blockUninstall, userId);
13386             mSettings.writePackageRestrictionsLPr(userId);
13387         }
13388         return true;
13389     }
13390
13391     @Override
13392     public boolean getBlockUninstallForUser(String packageName, int userId) {
13393         synchronized (mPackages) {
13394             PackageSetting ps = mSettings.mPackages.get(packageName);
13395             if (ps == null) {
13396                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
13397                 return false;
13398             }
13399             return ps.getBlockUninstall(userId);
13400         }
13401     }
13402
13403     /*
13404      * This method handles package deletion in general
13405      */
13406     private boolean deletePackageLI(String packageName, UserHandle user,
13407             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
13408             int flags, PackageRemovedInfo outInfo,
13409             boolean writeSettings) {
13410         if (packageName == null) {
13411             Slog.w(TAG, "Attempt to delete null packageName.");
13412             return false;
13413         }
13414         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
13415         PackageSetting ps;
13416         boolean dataOnly = false;
13417         int removeUser = -1;
13418         int appId = -1;
13419         synchronized (mPackages) {
13420             ps = mSettings.mPackages.get(packageName);
13421             if (ps == null) {
13422                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
13423                 return false;
13424             }
13425             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
13426                     && user.getIdentifier() != UserHandle.USER_ALL) {
13427                 // The caller is asking that the package only be deleted for a single
13428                 // user.  To do this, we just mark its uninstalled state and delete
13429                 // its data.  If this is a system app, we only allow this to happen if
13430                 // they have set the special DELETE_SYSTEM_APP which requests different
13431                 // semantics than normal for uninstalling system apps.
13432                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
13433                 final int userId = user.getIdentifier();
13434                 ps.setUserState(userId,
13435                         COMPONENT_ENABLED_STATE_DEFAULT,
13436                         false, //installed
13437                         true,  //stopped
13438                         true,  //notLaunched
13439                         false, //hidden
13440                         null, null, null,
13441                         false, // blockUninstall
13442                         ps.readUserState(userId).domainVerificationStatus, 0);
13443                 if (!isSystemApp(ps)) {
13444                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
13445                         // Other user still have this package installed, so all
13446                         // we need to do is clear this user's data and save that
13447                         // it is uninstalled.
13448                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
13449                         removeUser = user.getIdentifier();
13450                         appId = ps.appId;
13451                         scheduleWritePackageRestrictionsLocked(removeUser);
13452                     } else {
13453                         // We need to set it back to 'installed' so the uninstall
13454                         // broadcasts will be sent correctly.
13455                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
13456                         ps.setInstalled(true, user.getIdentifier());
13457                     }
13458                 } else {
13459                     // This is a system app, so we assume that the
13460                     // other users still have this package installed, so all
13461                     // we need to do is clear this user's data and save that
13462                     // it is uninstalled.
13463                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
13464                     removeUser = user.getIdentifier();
13465                     appId = ps.appId;
13466                     scheduleWritePackageRestrictionsLocked(removeUser);
13467                 }
13468             }
13469         }
13470
13471         if (removeUser >= 0) {
13472             // From above, we determined that we are deleting this only
13473             // for a single user.  Continue the work here.
13474             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
13475             if (outInfo != null) {
13476                 outInfo.removedPackage = packageName;
13477                 outInfo.removedAppId = appId;
13478                 outInfo.removedUsers = new int[] {removeUser};
13479             }
13480             mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser);
13481             removeKeystoreDataIfNeeded(removeUser, appId);
13482             schedulePackageCleaning(packageName, removeUser, false);
13483             synchronized (mPackages) {
13484                 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
13485                     scheduleWritePackageRestrictionsLocked(removeUser);
13486                 }
13487                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser);
13488             }
13489             return true;
13490         }
13491
13492         if (dataOnly) {
13493             // Delete application data first
13494             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
13495             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
13496             return true;
13497         }
13498
13499         boolean ret = false;
13500         if (isSystemApp(ps)) {
13501             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
13502             // When an updated system application is deleted we delete the existing resources as well and
13503             // fall back to existing code in system partition
13504             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
13505                     flags, outInfo, writeSettings);
13506         } else {
13507             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
13508             // Kill application pre-emptively especially for apps on sd.
13509             killApplication(packageName, ps.appId, "uninstall pkg");
13510             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
13511                     allUserHandles, perUserInstalled,
13512                     outInfo, writeSettings);
13513         }
13514
13515         return ret;
13516     }
13517
13518     private final class ClearStorageConnection implements ServiceConnection {
13519         IMediaContainerService mContainerService;
13520
13521         @Override
13522         public void onServiceConnected(ComponentName name, IBinder service) {
13523             synchronized (this) {
13524                 mContainerService = IMediaContainerService.Stub.asInterface(service);
13525                 notifyAll();
13526             }
13527         }
13528
13529         @Override
13530         public void onServiceDisconnected(ComponentName name) {
13531         }
13532     }
13533
13534     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
13535         final boolean mounted;
13536         if (Environment.isExternalStorageEmulated()) {
13537             mounted = true;
13538         } else {
13539             final String status = Environment.getExternalStorageState();
13540
13541             mounted = status.equals(Environment.MEDIA_MOUNTED)
13542                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
13543         }
13544
13545         if (!mounted) {
13546             return;
13547         }
13548
13549         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
13550         int[] users;
13551         if (userId == UserHandle.USER_ALL) {
13552             users = sUserManager.getUserIds();
13553         } else {
13554             users = new int[] { userId };
13555         }
13556         final ClearStorageConnection conn = new ClearStorageConnection();
13557         if (mContext.bindServiceAsUser(
13558                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
13559             try {
13560                 for (int curUser : users) {
13561                     long timeout = SystemClock.uptimeMillis() + 5000;
13562                     synchronized (conn) {
13563                         long now = SystemClock.uptimeMillis();
13564                         while (conn.mContainerService == null && now < timeout) {
13565                             try {
13566                                 conn.wait(timeout - now);
13567                             } catch (InterruptedException e) {
13568                             }
13569                         }
13570                     }
13571                     if (conn.mContainerService == null) {
13572                         return;
13573                     }
13574
13575                     final UserEnvironment userEnv = new UserEnvironment(curUser);
13576                     clearDirectory(conn.mContainerService,
13577                             userEnv.buildExternalStorageAppCacheDirs(packageName));
13578                     if (allData) {
13579                         clearDirectory(conn.mContainerService,
13580                                 userEnv.buildExternalStorageAppDataDirs(packageName));
13581                         clearDirectory(conn.mContainerService,
13582                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
13583                     }
13584                 }
13585             } finally {
13586                 mContext.unbindService(conn);
13587             }
13588         }
13589     }
13590
13591     @Override
13592     public void clearApplicationUserData(final String packageName,
13593             final IPackageDataObserver observer, final int userId) {
13594         mContext.enforceCallingOrSelfPermission(
13595                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
13596         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
13597         // Queue up an async operation since the package deletion may take a little while.
13598         mHandler.post(new Runnable() {
13599             public void run() {
13600                 mHandler.removeCallbacks(this);
13601                 final boolean succeeded;
13602                 synchronized (mInstallLock) {
13603                     succeeded = clearApplicationUserDataLI(packageName, userId);
13604                 }
13605                 clearExternalStorageDataSync(packageName, userId, true);
13606                 if (succeeded) {
13607                     // invoke DeviceStorageMonitor's update method to clear any notifications
13608                     DeviceStorageMonitorInternal
13609                             dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13610                     if (dsm != null) {
13611                         dsm.checkMemory();
13612                     }
13613                 }
13614                 if(observer != null) {
13615                     try {
13616                         observer.onRemoveCompleted(packageName, succeeded);
13617                     } catch (RemoteException e) {
13618                         Log.i(TAG, "Observer no longer exists.");
13619                     }
13620                 } //end if observer
13621             } //end run
13622         });
13623     }
13624
13625     private boolean clearApplicationUserDataLI(String packageName, int userId) {
13626         if (packageName == null) {
13627             Slog.w(TAG, "Attempt to delete null packageName.");
13628             return false;
13629         }
13630
13631         // Try finding details about the requested package
13632         PackageParser.Package pkg;
13633         synchronized (mPackages) {
13634             pkg = mPackages.get(packageName);
13635             if (pkg == null) {
13636                 final PackageSetting ps = mSettings.mPackages.get(packageName);
13637                 if (ps != null) {
13638                     pkg = ps.pkg;
13639                 }
13640             }
13641
13642             if (pkg == null) {
13643                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
13644                 return false;
13645             }
13646
13647             PackageSetting ps = (PackageSetting) pkg.mExtras;
13648             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
13649         }
13650
13651         // Always delete data directories for package, even if we found no other
13652         // record of app. This helps users recover from UID mismatches without
13653         // resorting to a full data wipe.
13654         int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId);
13655         if (retCode < 0) {
13656             Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
13657             return false;
13658         }
13659
13660         final int appId = pkg.applicationInfo.uid;
13661         removeKeystoreDataIfNeeded(userId, appId);
13662
13663         // Create a native library symlink only if we have native libraries
13664         // and if the native libraries are 32 bit libraries. We do not provide
13665         // this symlink for 64 bit libraries.
13666         if (pkg.applicationInfo.primaryCpuAbi != null &&
13667                 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
13668             final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
13669             if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
13670                     nativeLibPath, userId) < 0) {
13671                 Slog.w(TAG, "Failed linking native library dir");
13672                 return false;
13673             }
13674         }
13675
13676         return true;
13677     }
13678
13679     /**
13680      * Reverts user permission state changes (permissions and flags) in
13681      * all packages for a given user.
13682      *
13683      * @param userId The device user for which to do a reset.
13684      */
13685     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
13686         final int packageCount = mPackages.size();
13687         for (int i = 0; i < packageCount; i++) {
13688             PackageParser.Package pkg = mPackages.valueAt(i);
13689             PackageSetting ps = (PackageSetting) pkg.mExtras;
13690             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
13691         }
13692     }
13693
13694     /**
13695      * Reverts user permission state changes (permissions and flags).
13696      *
13697      * @param ps The package for which to reset.
13698      * @param userId The device user for which to do a reset.
13699      */
13700     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
13701             final PackageSetting ps, final int userId) {
13702         if (ps.pkg == null) {
13703             return;
13704         }
13705
13706         final int userSettableFlags = FLAG_PERMISSION_USER_SET
13707                 | FLAG_PERMISSION_USER_FIXED
13708                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
13709
13710         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
13711                 | FLAG_PERMISSION_POLICY_FIXED;
13712
13713         boolean writeInstallPermissions = false;
13714         boolean writeRuntimePermissions = false;
13715
13716         final int permissionCount = ps.pkg.requestedPermissions.size();
13717         for (int i = 0; i < permissionCount; i++) {
13718             String permission = ps.pkg.requestedPermissions.get(i);
13719
13720             BasePermission bp = mSettings.mPermissions.get(permission);
13721             if (bp == null) {
13722                 continue;
13723             }
13724
13725             // If shared user we just reset the state to which only this app contributed.
13726             if (ps.sharedUser != null) {
13727                 boolean used = false;
13728                 final int packageCount = ps.sharedUser.packages.size();
13729                 for (int j = 0; j < packageCount; j++) {
13730                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
13731                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
13732                             && pkg.pkg.requestedPermissions.contains(permission)) {
13733                         used = true;
13734                         break;
13735                     }
13736                 }
13737                 if (used) {
13738                     continue;
13739                 }
13740             }
13741
13742             PermissionsState permissionsState = ps.getPermissionsState();
13743
13744             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
13745
13746             // Always clear the user settable flags.
13747             final boolean hasInstallState = permissionsState.getInstallPermissionState(
13748                     bp.name) != null;
13749             if (permissionsState.updatePermissionFlags(bp, userId, userSettableFlags, 0)) {
13750                 if (hasInstallState) {
13751                     writeInstallPermissions = true;
13752                 } else {
13753                     writeRuntimePermissions = true;
13754                 }
13755             }
13756
13757             // Below is only runtime permission handling.
13758             if (!bp.isRuntime()) {
13759                 continue;
13760             }
13761
13762             // Never clobber system or policy.
13763             if ((oldFlags & policyOrSystemFlags) != 0) {
13764                 continue;
13765             }
13766
13767             // If this permission was granted by default, make sure it is.
13768             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
13769                 if (permissionsState.grantRuntimePermission(bp, userId)
13770                         != PERMISSION_OPERATION_FAILURE) {
13771                     writeRuntimePermissions = true;
13772                 }
13773             } else {
13774                 // Otherwise, reset the permission.
13775                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
13776                 switch (revokeResult) {
13777                     case PERMISSION_OPERATION_SUCCESS: {
13778                         writeRuntimePermissions = true;
13779                     } break;
13780
13781                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
13782                         writeRuntimePermissions = true;
13783                         final int appId = ps.appId;
13784                         mHandler.post(new Runnable() {
13785                             @Override
13786                             public void run() {
13787                                 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
13788                             }
13789                         });
13790                     } break;
13791                 }
13792             }
13793         }
13794
13795         // Synchronously write as we are taking permissions away.
13796         if (writeRuntimePermissions) {
13797             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
13798         }
13799
13800         // Synchronously write as we are taking permissions away.
13801         if (writeInstallPermissions) {
13802             mSettings.writeLPr();
13803         }
13804     }
13805
13806     /**
13807      * Remove entries from the keystore daemon. Will only remove it if the
13808      * {@code appId} is valid.
13809      */
13810     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
13811         if (appId < 0) {
13812             return;
13813         }
13814
13815         final KeyStore keyStore = KeyStore.getInstance();
13816         if (keyStore != null) {
13817             if (userId == UserHandle.USER_ALL) {
13818                 for (final int individual : sUserManager.getUserIds()) {
13819                     keyStore.clearUid(UserHandle.getUid(individual, appId));
13820                 }
13821             } else {
13822                 keyStore.clearUid(UserHandle.getUid(userId, appId));
13823             }
13824         } else {
13825             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
13826         }
13827     }
13828
13829     @Override
13830     public void deleteApplicationCacheFiles(final String packageName,
13831             final IPackageDataObserver observer) {
13832         mContext.enforceCallingOrSelfPermission(
13833                 android.Manifest.permission.DELETE_CACHE_FILES, null);
13834         // Queue up an async operation since the package deletion may take a little while.
13835         final int userId = UserHandle.getCallingUserId();
13836         mHandler.post(new Runnable() {
13837             public void run() {
13838                 mHandler.removeCallbacks(this);
13839                 final boolean succeded;
13840                 synchronized (mInstallLock) {
13841                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
13842                 }
13843                 clearExternalStorageDataSync(packageName, userId, false);
13844                 if (observer != null) {
13845                     try {
13846                         observer.onRemoveCompleted(packageName, succeded);
13847                     } catch (RemoteException e) {
13848                         Log.i(TAG, "Observer no longer exists.");
13849                     }
13850                 } //end if observer
13851             } //end run
13852         });
13853     }
13854
13855     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
13856         if (packageName == null) {
13857             Slog.w(TAG, "Attempt to delete null packageName.");
13858             return false;
13859         }
13860         PackageParser.Package p;
13861         synchronized (mPackages) {
13862             p = mPackages.get(packageName);
13863         }
13864         if (p == null) {
13865             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
13866             return false;
13867         }
13868         final ApplicationInfo applicationInfo = p.applicationInfo;
13869         if (applicationInfo == null) {
13870             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
13871             return false;
13872         }
13873         int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId);
13874         if (retCode < 0) {
13875             Slog.w(TAG, "Couldn't remove cache files for package: "
13876                        + packageName + " u" + userId);
13877             return false;
13878         }
13879         return true;
13880     }
13881
13882     @Override
13883     public void getPackageSizeInfo(final String packageName, int userHandle,
13884             final IPackageStatsObserver observer) {
13885         mContext.enforceCallingOrSelfPermission(
13886                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
13887         if (packageName == null) {
13888             throw new IllegalArgumentException("Attempt to get size of null packageName");
13889         }
13890
13891         PackageStats stats = new PackageStats(packageName, userHandle);
13892
13893         /*
13894          * Queue up an async operation since the package measurement may take a
13895          * little while.
13896          */
13897         Message msg = mHandler.obtainMessage(INIT_COPY);
13898         msg.obj = new MeasureParams(stats, observer);
13899         mHandler.sendMessage(msg);
13900     }
13901
13902     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
13903             PackageStats pStats) {
13904         if (packageName == null) {
13905             Slog.w(TAG, "Attempt to get size of null packageName.");
13906             return false;
13907         }
13908         PackageParser.Package p;
13909         boolean dataOnly = false;
13910         String libDirRoot = null;
13911         String asecPath = null;
13912         PackageSetting ps = null;
13913         synchronized (mPackages) {
13914             p = mPackages.get(packageName);
13915             ps = mSettings.mPackages.get(packageName);
13916             if(p == null) {
13917                 dataOnly = true;
13918                 if((ps == null) || (ps.pkg == null)) {
13919                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
13920                     return false;
13921                 }
13922                 p = ps.pkg;
13923             }
13924             if (ps != null) {
13925                 libDirRoot = ps.legacyNativeLibraryPathString;
13926             }
13927             if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
13928                 final long token = Binder.clearCallingIdentity();
13929                 try {
13930                     String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
13931                     if (secureContainerId != null) {
13932                         asecPath = PackageHelper.getSdFilesystem(secureContainerId);
13933                     }
13934                 } finally {
13935                     Binder.restoreCallingIdentity(token);
13936                 }
13937             }
13938         }
13939         String publicSrcDir = null;
13940         if(!dataOnly) {
13941             final ApplicationInfo applicationInfo = p.applicationInfo;
13942             if (applicationInfo == null) {
13943                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
13944                 return false;
13945             }
13946             if (p.isForwardLocked()) {
13947                 publicSrcDir = applicationInfo.getBaseResourcePath();
13948             }
13949         }
13950         // TODO: extend to measure size of split APKs
13951         // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
13952         // not just the first level.
13953         // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
13954         // just the primary.
13955         String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
13956
13957         String apkPath;
13958         File packageDir = new File(p.codePath);
13959
13960         if (packageDir.isDirectory() && p.canHaveOatDir()) {
13961             apkPath = packageDir.getAbsolutePath();
13962             // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
13963             if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
13964                 libDirRoot = null;
13965             }
13966         } else {
13967             apkPath = p.baseCodePath;
13968         }
13969
13970         int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath,
13971                 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
13972         if (res < 0) {
13973             return false;
13974         }
13975
13976         // Fix-up for forward-locked applications in ASEC containers.
13977         if (!isExternal(p)) {
13978             pStats.codeSize += pStats.externalCodeSize;
13979             pStats.externalCodeSize = 0L;
13980         }
13981
13982         return true;
13983     }
13984
13985
13986     @Override
13987     public void addPackageToPreferred(String packageName) {
13988         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
13989     }
13990
13991     @Override
13992     public void removePackageFromPreferred(String packageName) {
13993         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
13994     }
13995
13996     @Override
13997     public List<PackageInfo> getPreferredPackages(int flags) {
13998         return new ArrayList<PackageInfo>();
13999     }
14000
14001     private int getUidTargetSdkVersionLockedLPr(int uid) {
14002         Object obj = mSettings.getUserIdLPr(uid);
14003         if (obj instanceof SharedUserSetting) {
14004             final SharedUserSetting sus = (SharedUserSetting) obj;
14005             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
14006             final Iterator<PackageSetting> it = sus.packages.iterator();
14007             while (it.hasNext()) {
14008                 final PackageSetting ps = it.next();
14009                 if (ps.pkg != null) {
14010                     int v = ps.pkg.applicationInfo.targetSdkVersion;
14011                     if (v < vers) vers = v;
14012                 }
14013             }
14014             return vers;
14015         } else if (obj instanceof PackageSetting) {
14016             final PackageSetting ps = (PackageSetting) obj;
14017             if (ps.pkg != null) {
14018                 return ps.pkg.applicationInfo.targetSdkVersion;
14019             }
14020         }
14021         return Build.VERSION_CODES.CUR_DEVELOPMENT;
14022     }
14023
14024     @Override
14025     public void addPreferredActivity(IntentFilter filter, int match,
14026             ComponentName[] set, ComponentName activity, int userId) {
14027         addPreferredActivityInternal(filter, match, set, activity, true, userId,
14028                 "Adding preferred");
14029     }
14030
14031     private void addPreferredActivityInternal(IntentFilter filter, int match,
14032             ComponentName[] set, ComponentName activity, boolean always, int userId,
14033             String opname) {
14034         // writer
14035         int callingUid = Binder.getCallingUid();
14036         enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
14037         if (filter.countActions() == 0) {
14038             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14039             return;
14040         }
14041         synchronized (mPackages) {
14042             if (mContext.checkCallingOrSelfPermission(
14043                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14044                     != PackageManager.PERMISSION_GRANTED) {
14045                 if (getUidTargetSdkVersionLockedLPr(callingUid)
14046                         < Build.VERSION_CODES.FROYO) {
14047                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
14048                             + callingUid);
14049                     return;
14050                 }
14051                 mContext.enforceCallingOrSelfPermission(
14052                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14053             }
14054
14055             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
14056             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
14057                     + userId + ":");
14058             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14059             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
14060             scheduleWritePackageRestrictionsLocked(userId);
14061         }
14062     }
14063
14064     @Override
14065     public void replacePreferredActivity(IntentFilter filter, int match,
14066             ComponentName[] set, ComponentName activity, int userId) {
14067         if (filter.countActions() != 1) {
14068             throw new IllegalArgumentException(
14069                     "replacePreferredActivity expects filter to have only 1 action.");
14070         }
14071         if (filter.countDataAuthorities() != 0
14072                 || filter.countDataPaths() != 0
14073                 || filter.countDataSchemes() > 1
14074                 || filter.countDataTypes() != 0) {
14075             throw new IllegalArgumentException(
14076                     "replacePreferredActivity expects filter to have no data authorities, " +
14077                     "paths, or types; and at most one scheme.");
14078         }
14079
14080         final int callingUid = Binder.getCallingUid();
14081         enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
14082         synchronized (mPackages) {
14083             if (mContext.checkCallingOrSelfPermission(
14084                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14085                     != PackageManager.PERMISSION_GRANTED) {
14086                 if (getUidTargetSdkVersionLockedLPr(callingUid)
14087                         < Build.VERSION_CODES.FROYO) {
14088                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
14089                             + Binder.getCallingUid());
14090                     return;
14091                 }
14092                 mContext.enforceCallingOrSelfPermission(
14093                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14094             }
14095
14096             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14097             if (pir != null) {
14098                 // Get all of the existing entries that exactly match this filter.
14099                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
14100                 if (existing != null && existing.size() == 1) {
14101                     PreferredActivity cur = existing.get(0);
14102                     if (DEBUG_PREFERRED) {
14103                         Slog.i(TAG, "Checking replace of preferred:");
14104                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14105                         if (!cur.mPref.mAlways) {
14106                             Slog.i(TAG, "  -- CUR; not mAlways!");
14107                         } else {
14108                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
14109                             Slog.i(TAG, "  -- CUR: mSet="
14110                                     + Arrays.toString(cur.mPref.mSetComponents));
14111                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
14112                             Slog.i(TAG, "  -- NEW: mMatch="
14113                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
14114                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
14115                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
14116                         }
14117                     }
14118                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
14119                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
14120                             && cur.mPref.sameSet(set)) {
14121                         // Setting the preferred activity to what it happens to be already
14122                         if (DEBUG_PREFERRED) {
14123                             Slog.i(TAG, "Replacing with same preferred activity "
14124                                     + cur.mPref.mShortComponent + " for user "
14125                                     + userId + ":");
14126                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14127                         }
14128                         return;
14129                     }
14130                 }
14131
14132                 if (existing != null) {
14133                     if (DEBUG_PREFERRED) {
14134                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
14135                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14136                     }
14137                     for (int i = 0; i < existing.size(); i++) {
14138                         PreferredActivity pa = existing.get(i);
14139                         if (DEBUG_PREFERRED) {
14140                             Slog.i(TAG, "Removing existing preferred activity "
14141                                     + pa.mPref.mComponent + ":");
14142                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
14143                         }
14144                         pir.removeFilter(pa);
14145                     }
14146                 }
14147             }
14148             addPreferredActivityInternal(filter, match, set, activity, true, userId,
14149                     "Replacing preferred");
14150         }
14151     }
14152
14153     @Override
14154     public void clearPackagePreferredActivities(String packageName) {
14155         final int uid = Binder.getCallingUid();
14156         // writer
14157         synchronized (mPackages) {
14158             PackageParser.Package pkg = mPackages.get(packageName);
14159             if (pkg == null || pkg.applicationInfo.uid != uid) {
14160                 if (mContext.checkCallingOrSelfPermission(
14161                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14162                         != PackageManager.PERMISSION_GRANTED) {
14163                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
14164                             < Build.VERSION_CODES.FROYO) {
14165                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
14166                                 + Binder.getCallingUid());
14167                         return;
14168                     }
14169                     mContext.enforceCallingOrSelfPermission(
14170                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14171                 }
14172             }
14173
14174             int user = UserHandle.getCallingUserId();
14175             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
14176                 scheduleWritePackageRestrictionsLocked(user);
14177             }
14178         }
14179     }
14180
14181     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14182     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
14183         ArrayList<PreferredActivity> removed = null;
14184         boolean changed = false;
14185         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14186             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
14187             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14188             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
14189                 continue;
14190             }
14191             Iterator<PreferredActivity> it = pir.filterIterator();
14192             while (it.hasNext()) {
14193                 PreferredActivity pa = it.next();
14194                 // Mark entry for removal only if it matches the package name
14195                 // and the entry is of type "always".
14196                 if (packageName == null ||
14197                         (pa.mPref.mComponent.getPackageName().equals(packageName)
14198                                 && pa.mPref.mAlways)) {
14199                     if (removed == null) {
14200                         removed = new ArrayList<PreferredActivity>();
14201                     }
14202                     removed.add(pa);
14203                 }
14204             }
14205             if (removed != null) {
14206                 for (int j=0; j<removed.size(); j++) {
14207                     PreferredActivity pa = removed.get(j);
14208                     pir.removeFilter(pa);
14209                 }
14210                 changed = true;
14211             }
14212         }
14213         return changed;
14214     }
14215
14216     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14217     private void clearIntentFilterVerificationsLPw(int userId) {
14218         final int packageCount = mPackages.size();
14219         for (int i = 0; i < packageCount; i++) {
14220             PackageParser.Package pkg = mPackages.valueAt(i);
14221             clearIntentFilterVerificationsLPw(pkg.packageName, userId);
14222         }
14223     }
14224
14225     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14226     void clearIntentFilterVerificationsLPw(String packageName, int userId) {
14227         if (userId == UserHandle.USER_ALL) {
14228             if (mSettings.removeIntentFilterVerificationLPw(packageName,
14229                     sUserManager.getUserIds())) {
14230                 for (int oneUserId : sUserManager.getUserIds()) {
14231                     scheduleWritePackageRestrictionsLocked(oneUserId);
14232                 }
14233             }
14234         } else {
14235             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
14236                 scheduleWritePackageRestrictionsLocked(userId);
14237             }
14238         }
14239     }
14240
14241     void clearDefaultBrowserIfNeeded(String packageName) {
14242         for (int oneUserId : sUserManager.getUserIds()) {
14243             String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
14244             if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
14245             if (packageName.equals(defaultBrowserPackageName)) {
14246                 setDefaultBrowserPackageName(null, oneUserId);
14247             }
14248         }
14249     }
14250
14251     @Override
14252     public void resetApplicationPreferences(int userId) {
14253         mContext.enforceCallingOrSelfPermission(
14254                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14255         // writer
14256         synchronized (mPackages) {
14257             final long identity = Binder.clearCallingIdentity();
14258             try {
14259                 clearPackagePreferredActivitiesLPw(null, userId);
14260                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
14261                 // TODO: We have to reset the default SMS and Phone. This requires
14262                 // significant refactoring to keep all default apps in the package
14263                 // manager (cleaner but more work) or have the services provide
14264                 // callbacks to the package manager to request a default app reset.
14265                 applyFactoryDefaultBrowserLPw(userId);
14266                 clearIntentFilterVerificationsLPw(userId);
14267                 primeDomainVerificationsLPw(userId);
14268                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
14269                 scheduleWritePackageRestrictionsLocked(userId);
14270             } finally {
14271                 Binder.restoreCallingIdentity(identity);
14272             }
14273         }
14274     }
14275
14276     @Override
14277     public int getPreferredActivities(List<IntentFilter> outFilters,
14278             List<ComponentName> outActivities, String packageName) {
14279
14280         int num = 0;
14281         final int userId = UserHandle.getCallingUserId();
14282         // reader
14283         synchronized (mPackages) {
14284             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14285             if (pir != null) {
14286                 final Iterator<PreferredActivity> it = pir.filterIterator();
14287                 while (it.hasNext()) {
14288                     final PreferredActivity pa = it.next();
14289                     if (packageName == null
14290                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
14291                                     && pa.mPref.mAlways)) {
14292                         if (outFilters != null) {
14293                             outFilters.add(new IntentFilter(pa));
14294                         }
14295                         if (outActivities != null) {
14296                             outActivities.add(pa.mPref.mComponent);
14297                         }
14298                     }
14299                 }
14300             }
14301         }
14302
14303         return num;
14304     }
14305
14306     @Override
14307     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
14308             int userId) {
14309         int callingUid = Binder.getCallingUid();
14310         if (callingUid != Process.SYSTEM_UID) {
14311             throw new SecurityException(
14312                     "addPersistentPreferredActivity can only be run by the system");
14313         }
14314         if (filter.countActions() == 0) {
14315             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14316             return;
14317         }
14318         synchronized (mPackages) {
14319             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
14320                     " :");
14321             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14322             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
14323                     new PersistentPreferredActivity(filter, activity));
14324             scheduleWritePackageRestrictionsLocked(userId);
14325         }
14326     }
14327
14328     @Override
14329     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
14330         int callingUid = Binder.getCallingUid();
14331         if (callingUid != Process.SYSTEM_UID) {
14332             throw new SecurityException(
14333                     "clearPackagePersistentPreferredActivities can only be run by the system");
14334         }
14335         ArrayList<PersistentPreferredActivity> removed = null;
14336         boolean changed = false;
14337         synchronized (mPackages) {
14338             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
14339                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
14340                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
14341                         .valueAt(i);
14342                 if (userId != thisUserId) {
14343                     continue;
14344                 }
14345                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
14346                 while (it.hasNext()) {
14347                     PersistentPreferredActivity ppa = it.next();
14348                     // Mark entry for removal only if it matches the package name.
14349                     if (ppa.mComponent.getPackageName().equals(packageName)) {
14350                         if (removed == null) {
14351                             removed = new ArrayList<PersistentPreferredActivity>();
14352                         }
14353                         removed.add(ppa);
14354                     }
14355                 }
14356                 if (removed != null) {
14357                     for (int j=0; j<removed.size(); j++) {
14358                         PersistentPreferredActivity ppa = removed.get(j);
14359                         ppir.removeFilter(ppa);
14360                     }
14361                     changed = true;
14362                 }
14363             }
14364
14365             if (changed) {
14366                 scheduleWritePackageRestrictionsLocked(userId);
14367             }
14368         }
14369     }
14370
14371     /**
14372      * Common machinery for picking apart a restored XML blob and passing
14373      * it to a caller-supplied functor to be applied to the running system.
14374      */
14375     private void restoreFromXml(XmlPullParser parser, int userId,
14376             String expectedStartTag, BlobXmlRestorer functor)
14377             throws IOException, XmlPullParserException {
14378         int type;
14379         while ((type = parser.next()) != XmlPullParser.START_TAG
14380                 && type != XmlPullParser.END_DOCUMENT) {
14381         }
14382         if (type != XmlPullParser.START_TAG) {
14383             // oops didn't find a start tag?!
14384             if (DEBUG_BACKUP) {
14385                 Slog.e(TAG, "Didn't find start tag during restore");
14386             }
14387             return;
14388         }
14389
14390         // this is supposed to be TAG_PREFERRED_BACKUP
14391         if (!expectedStartTag.equals(parser.getName())) {
14392             if (DEBUG_BACKUP) {
14393                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
14394             }
14395             return;
14396         }
14397
14398         // skip interfering stuff, then we're aligned with the backing implementation
14399         while ((type = parser.next()) == XmlPullParser.TEXT) { }
14400         functor.apply(parser, userId);
14401     }
14402
14403     private interface BlobXmlRestorer {
14404         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
14405     }
14406
14407     /**
14408      * Non-Binder method, support for the backup/restore mechanism: write the
14409      * full set of preferred activities in its canonical XML format.  Returns the
14410      * XML output as a byte array, or null if there is none.
14411      */
14412     @Override
14413     public byte[] getPreferredActivityBackup(int userId) {
14414         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14415             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
14416         }
14417
14418         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14419         try {
14420             final XmlSerializer serializer = new FastXmlSerializer();
14421             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14422             serializer.startDocument(null, true);
14423             serializer.startTag(null, TAG_PREFERRED_BACKUP);
14424
14425             synchronized (mPackages) {
14426                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
14427             }
14428
14429             serializer.endTag(null, TAG_PREFERRED_BACKUP);
14430             serializer.endDocument();
14431             serializer.flush();
14432         } catch (Exception e) {
14433             if (DEBUG_BACKUP) {
14434                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
14435             }
14436             return null;
14437         }
14438
14439         return dataStream.toByteArray();
14440     }
14441
14442     @Override
14443     public void restorePreferredActivities(byte[] backup, int userId) {
14444         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14445             throw new SecurityException("Only the system may call restorePreferredActivities()");
14446         }
14447
14448         try {
14449             final XmlPullParser parser = Xml.newPullParser();
14450             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14451             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
14452                     new BlobXmlRestorer() {
14453                         @Override
14454                         public void apply(XmlPullParser parser, int userId)
14455                                 throws XmlPullParserException, IOException {
14456                             synchronized (mPackages) {
14457                                 mSettings.readPreferredActivitiesLPw(parser, userId);
14458                             }
14459                         }
14460                     } );
14461         } catch (Exception e) {
14462             if (DEBUG_BACKUP) {
14463                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14464             }
14465         }
14466     }
14467
14468     /**
14469      * Non-Binder method, support for the backup/restore mechanism: write the
14470      * default browser (etc) settings in its canonical XML format.  Returns the default
14471      * browser XML representation as a byte array, or null if there is none.
14472      */
14473     @Override
14474     public byte[] getDefaultAppsBackup(int userId) {
14475         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14476             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
14477         }
14478
14479         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14480         try {
14481             final XmlSerializer serializer = new FastXmlSerializer();
14482             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14483             serializer.startDocument(null, true);
14484             serializer.startTag(null, TAG_DEFAULT_APPS);
14485
14486             synchronized (mPackages) {
14487                 mSettings.writeDefaultAppsLPr(serializer, userId);
14488             }
14489
14490             serializer.endTag(null, TAG_DEFAULT_APPS);
14491             serializer.endDocument();
14492             serializer.flush();
14493         } catch (Exception e) {
14494             if (DEBUG_BACKUP) {
14495                 Slog.e(TAG, "Unable to write default apps for backup", e);
14496             }
14497             return null;
14498         }
14499
14500         return dataStream.toByteArray();
14501     }
14502
14503     @Override
14504     public void restoreDefaultApps(byte[] backup, int userId) {
14505         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14506             throw new SecurityException("Only the system may call restoreDefaultApps()");
14507         }
14508
14509         try {
14510             final XmlPullParser parser = Xml.newPullParser();
14511             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14512             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
14513                     new BlobXmlRestorer() {
14514                         @Override
14515                         public void apply(XmlPullParser parser, int userId)
14516                                 throws XmlPullParserException, IOException {
14517                             synchronized (mPackages) {
14518                                 mSettings.readDefaultAppsLPw(parser, userId);
14519                             }
14520                         }
14521                     } );
14522         } catch (Exception e) {
14523             if (DEBUG_BACKUP) {
14524                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
14525             }
14526         }
14527     }
14528
14529     @Override
14530     public byte[] getIntentFilterVerificationBackup(int userId) {
14531         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14532             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
14533         }
14534
14535         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14536         try {
14537             final XmlSerializer serializer = new FastXmlSerializer();
14538             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14539             serializer.startDocument(null, true);
14540             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
14541
14542             synchronized (mPackages) {
14543                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
14544             }
14545
14546             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
14547             serializer.endDocument();
14548             serializer.flush();
14549         } catch (Exception e) {
14550             if (DEBUG_BACKUP) {
14551                 Slog.e(TAG, "Unable to write default apps for backup", e);
14552             }
14553             return null;
14554         }
14555
14556         return dataStream.toByteArray();
14557     }
14558
14559     @Override
14560     public void restoreIntentFilterVerification(byte[] backup, int userId) {
14561         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14562             throw new SecurityException("Only the system may call restorePreferredActivities()");
14563         }
14564
14565         try {
14566             final XmlPullParser parser = Xml.newPullParser();
14567             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14568             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
14569                     new BlobXmlRestorer() {
14570                         @Override
14571                         public void apply(XmlPullParser parser, int userId)
14572                                 throws XmlPullParserException, IOException {
14573                             synchronized (mPackages) {
14574                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
14575                                 mSettings.writeLPr();
14576                             }
14577                         }
14578                     } );
14579         } catch (Exception e) {
14580             if (DEBUG_BACKUP) {
14581                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14582             }
14583         }
14584     }
14585
14586     @Override
14587     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
14588             int sourceUserId, int targetUserId, int flags) {
14589         mContext.enforceCallingOrSelfPermission(
14590                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14591         int callingUid = Binder.getCallingUid();
14592         enforceOwnerRights(ownerPackage, callingUid);
14593         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
14594         if (intentFilter.countActions() == 0) {
14595             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
14596             return;
14597         }
14598         synchronized (mPackages) {
14599             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
14600                     ownerPackage, targetUserId, flags);
14601             CrossProfileIntentResolver resolver =
14602                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
14603             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
14604             // We have all those whose filter is equal. Now checking if the rest is equal as well.
14605             if (existing != null) {
14606                 int size = existing.size();
14607                 for (int i = 0; i < size; i++) {
14608                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
14609                         return;
14610                     }
14611                 }
14612             }
14613             resolver.addFilter(newFilter);
14614             scheduleWritePackageRestrictionsLocked(sourceUserId);
14615         }
14616     }
14617
14618     @Override
14619     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
14620         mContext.enforceCallingOrSelfPermission(
14621                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14622         int callingUid = Binder.getCallingUid();
14623         enforceOwnerRights(ownerPackage, callingUid);
14624         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
14625         synchronized (mPackages) {
14626             CrossProfileIntentResolver resolver =
14627                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
14628             ArraySet<CrossProfileIntentFilter> set =
14629                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
14630             for (CrossProfileIntentFilter filter : set) {
14631                 if (filter.getOwnerPackage().equals(ownerPackage)) {
14632                     resolver.removeFilter(filter);
14633                 }
14634             }
14635             scheduleWritePackageRestrictionsLocked(sourceUserId);
14636         }
14637     }
14638
14639     // Enforcing that callingUid is owning pkg on userId
14640     private void enforceOwnerRights(String pkg, int callingUid) {
14641         // The system owns everything.
14642         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
14643             return;
14644         }
14645         int callingUserId = UserHandle.getUserId(callingUid);
14646         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
14647         if (pi == null) {
14648             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
14649                     + callingUserId);
14650         }
14651         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
14652             throw new SecurityException("Calling uid " + callingUid
14653                     + " does not own package " + pkg);
14654         }
14655     }
14656
14657     @Override
14658     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
14659         Intent intent = new Intent(Intent.ACTION_MAIN);
14660         intent.addCategory(Intent.CATEGORY_HOME);
14661
14662         final int callingUserId = UserHandle.getCallingUserId();
14663         List<ResolveInfo> list = queryIntentActivities(intent, null,
14664                 PackageManager.GET_META_DATA, callingUserId);
14665         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
14666                 true, false, false, callingUserId);
14667
14668         allHomeCandidates.clear();
14669         if (list != null) {
14670             for (ResolveInfo ri : list) {
14671                 allHomeCandidates.add(ri);
14672             }
14673         }
14674         return (preferred == null || preferred.activityInfo == null)
14675                 ? null
14676                 : new ComponentName(preferred.activityInfo.packageName,
14677                         preferred.activityInfo.name);
14678     }
14679
14680     @Override
14681     public void setApplicationEnabledSetting(String appPackageName,
14682             int newState, int flags, int userId, String callingPackage) {
14683         if (!sUserManager.exists(userId)) return;
14684         if (callingPackage == null) {
14685             callingPackage = Integer.toString(Binder.getCallingUid());
14686         }
14687         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
14688     }
14689
14690     @Override
14691     public void setComponentEnabledSetting(ComponentName componentName,
14692             int newState, int flags, int userId) {
14693         if (!sUserManager.exists(userId)) return;
14694         setEnabledSetting(componentName.getPackageName(),
14695                 componentName.getClassName(), newState, flags, userId, null);
14696     }
14697
14698     private void setEnabledSetting(final String packageName, String className, int newState,
14699             final int flags, int userId, String callingPackage) {
14700         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
14701               || newState == COMPONENT_ENABLED_STATE_ENABLED
14702               || newState == COMPONENT_ENABLED_STATE_DISABLED
14703               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
14704               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
14705             throw new IllegalArgumentException("Invalid new component state: "
14706                     + newState);
14707         }
14708         PackageSetting pkgSetting;
14709         final int uid = Binder.getCallingUid();
14710         final int permission = mContext.checkCallingOrSelfPermission(
14711                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
14712         enforceCrossUserPermission(uid, userId, false, true, "set enabled");
14713         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
14714         boolean sendNow = false;
14715         boolean isApp = (className == null);
14716         String componentName = isApp ? packageName : className;
14717         int packageUid = -1;
14718         ArrayList<String> components;
14719
14720         // writer
14721         synchronized (mPackages) {
14722             pkgSetting = mSettings.mPackages.get(packageName);
14723             if (pkgSetting == null) {
14724                 if (className == null) {
14725                     throw new IllegalArgumentException(
14726                             "Unknown package: " + packageName);
14727                 }
14728                 throw new IllegalArgumentException(
14729                         "Unknown component: " + packageName
14730                         + "/" + className);
14731             }
14732             // Allow root and verify that userId is not being specified by a different user
14733             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
14734                 throw new SecurityException(
14735                         "Permission Denial: attempt to change component state from pid="
14736                         + Binder.getCallingPid()
14737                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
14738             }
14739             if (className == null) {
14740                 // We're dealing with an application/package level state change
14741                 if (pkgSetting.getEnabled(userId) == newState) {
14742                     // Nothing to do
14743                     return;
14744                 }
14745                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
14746                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
14747                     // Don't care about who enables an app.
14748                     callingPackage = null;
14749                 }
14750                 pkgSetting.setEnabled(newState, userId, callingPackage);
14751                 // pkgSetting.pkg.mSetEnabled = newState;
14752             } else {
14753                 // We're dealing with a component level state change
14754                 // First, verify that this is a valid class name.
14755                 PackageParser.Package pkg = pkgSetting.pkg;
14756                 if (pkg == null || !pkg.hasComponentClassName(className)) {
14757                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
14758                         throw new IllegalArgumentException("Component class " + className
14759                                 + " does not exist in " + packageName);
14760                     } else {
14761                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
14762                                 + className + " does not exist in " + packageName);
14763                     }
14764                 }
14765                 switch (newState) {
14766                 case COMPONENT_ENABLED_STATE_ENABLED:
14767                     if (!pkgSetting.enableComponentLPw(className, userId)) {
14768                         return;
14769                     }
14770                     break;
14771                 case COMPONENT_ENABLED_STATE_DISABLED:
14772                     if (!pkgSetting.disableComponentLPw(className, userId)) {
14773                         return;
14774                     }
14775                     break;
14776                 case COMPONENT_ENABLED_STATE_DEFAULT:
14777                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
14778                         return;
14779                     }
14780                     break;
14781                 default:
14782                     Slog.e(TAG, "Invalid new component state: " + newState);
14783                     return;
14784                 }
14785             }
14786             scheduleWritePackageRestrictionsLocked(userId);
14787             components = mPendingBroadcasts.get(userId, packageName);
14788             final boolean newPackage = components == null;
14789             if (newPackage) {
14790                 components = new ArrayList<String>();
14791             }
14792             if (!components.contains(componentName)) {
14793                 components.add(componentName);
14794             }
14795             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
14796                 sendNow = true;
14797                 // Purge entry from pending broadcast list if another one exists already
14798                 // since we are sending one right away.
14799                 mPendingBroadcasts.remove(userId, packageName);
14800             } else {
14801                 if (newPackage) {
14802                     mPendingBroadcasts.put(userId, packageName, components);
14803                 }
14804                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
14805                     // Schedule a message
14806                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
14807                 }
14808             }
14809         }
14810
14811         long callingId = Binder.clearCallingIdentity();
14812         try {
14813             if (sendNow) {
14814                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
14815                 sendPackageChangedBroadcast(packageName,
14816                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
14817             }
14818         } finally {
14819             Binder.restoreCallingIdentity(callingId);
14820         }
14821     }
14822
14823     private void sendPackageChangedBroadcast(String packageName,
14824             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
14825         if (DEBUG_INSTALL)
14826             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
14827                     + componentNames);
14828         Bundle extras = new Bundle(4);
14829         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
14830         String nameList[] = new String[componentNames.size()];
14831         componentNames.toArray(nameList);
14832         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
14833         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
14834         extras.putInt(Intent.EXTRA_UID, packageUid);
14835         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
14836                 new int[] {UserHandle.getUserId(packageUid)});
14837     }
14838
14839     @Override
14840     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
14841         if (!sUserManager.exists(userId)) return;
14842         final int uid = Binder.getCallingUid();
14843         final int permission = mContext.checkCallingOrSelfPermission(
14844                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
14845         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
14846         enforceCrossUserPermission(uid, userId, true, true, "stop package");
14847         // writer
14848         synchronized (mPackages) {
14849             if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
14850                     allowedByPermission, uid, userId)) {
14851                 scheduleWritePackageRestrictionsLocked(userId);
14852             }
14853         }
14854     }
14855
14856     @Override
14857     public String getInstallerPackageName(String packageName) {
14858         // reader
14859         synchronized (mPackages) {
14860             return mSettings.getInstallerPackageNameLPr(packageName);
14861         }
14862     }
14863
14864     @Override
14865     public int getApplicationEnabledSetting(String packageName, int userId) {
14866         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
14867         int uid = Binder.getCallingUid();
14868         enforceCrossUserPermission(uid, userId, false, false, "get enabled");
14869         // reader
14870         synchronized (mPackages) {
14871             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
14872         }
14873     }
14874
14875     @Override
14876     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
14877         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
14878         int uid = Binder.getCallingUid();
14879         enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
14880         // reader
14881         synchronized (mPackages) {
14882             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
14883         }
14884     }
14885
14886     @Override
14887     public void enterSafeMode() {
14888         enforceSystemOrRoot("Only the system can request entering safe mode");
14889
14890         if (!mSystemReady) {
14891             mSafeMode = true;
14892         }
14893     }
14894
14895     @Override
14896     public void systemReady() {
14897         mSystemReady = true;
14898
14899         // Read the compatibilty setting when the system is ready.
14900         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
14901                 mContext.getContentResolver(),
14902                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
14903         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
14904         if (DEBUG_SETTINGS) {
14905             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
14906         }
14907
14908         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
14909
14910         synchronized (mPackages) {
14911             // Verify that all of the preferred activity components actually
14912             // exist.  It is possible for applications to be updated and at
14913             // that point remove a previously declared activity component that
14914             // had been set as a preferred activity.  We try to clean this up
14915             // the next time we encounter that preferred activity, but it is
14916             // possible for the user flow to never be able to return to that
14917             // situation so here we do a sanity check to make sure we haven't
14918             // left any junk around.
14919             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
14920             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14921                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14922                 removed.clear();
14923                 for (PreferredActivity pa : pir.filterSet()) {
14924                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
14925                         removed.add(pa);
14926                     }
14927                 }
14928                 if (removed.size() > 0) {
14929                     for (int r=0; r<removed.size(); r++) {
14930                         PreferredActivity pa = removed.get(r);
14931                         Slog.w(TAG, "Removing dangling preferred activity: "
14932                                 + pa.mPref.mComponent);
14933                         pir.removeFilter(pa);
14934                     }
14935                     mSettings.writePackageRestrictionsLPr(
14936                             mSettings.mPreferredActivities.keyAt(i));
14937                 }
14938             }
14939
14940             for (int userId : UserManagerService.getInstance().getUserIds()) {
14941                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
14942                     grantPermissionsUserIds = ArrayUtils.appendInt(
14943                             grantPermissionsUserIds, userId);
14944                 }
14945             }
14946         }
14947         sUserManager.systemReady();
14948
14949         // If we upgraded grant all default permissions before kicking off.
14950         for (int userId : grantPermissionsUserIds) {
14951             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
14952         }
14953
14954         // Kick off any messages waiting for system ready
14955         if (mPostSystemReadyMessages != null) {
14956             for (Message msg : mPostSystemReadyMessages) {
14957                 msg.sendToTarget();
14958             }
14959             mPostSystemReadyMessages = null;
14960         }
14961
14962         // Watch for external volumes that come and go over time
14963         final StorageManager storage = mContext.getSystemService(StorageManager.class);
14964         storage.registerListener(mStorageListener);
14965
14966         mInstallerService.systemReady();
14967         mPackageDexOptimizer.systemReady();
14968
14969         MountServiceInternal mountServiceInternal = LocalServices.getService(
14970                 MountServiceInternal.class);
14971         mountServiceInternal.addExternalStoragePolicy(
14972                 new MountServiceInternal.ExternalStorageMountPolicy() {
14973             @Override
14974             public int getMountMode(int uid, String packageName) {
14975                 if (Process.isIsolated(uid)) {
14976                     return Zygote.MOUNT_EXTERNAL_NONE;
14977                 }
14978                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
14979                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
14980                 }
14981                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
14982                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
14983                 }
14984                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
14985                     return Zygote.MOUNT_EXTERNAL_READ;
14986                 }
14987                 return Zygote.MOUNT_EXTERNAL_WRITE;
14988             }
14989
14990             @Override
14991             public boolean hasExternalStorage(int uid, String packageName) {
14992                 return true;
14993             }
14994         });
14995     }
14996
14997     @Override
14998     public boolean isSafeMode() {
14999         return mSafeMode;
15000     }
15001
15002     @Override
15003     public boolean hasSystemUidErrors() {
15004         return mHasSystemUidErrors;
15005     }
15006
15007     static String arrayToString(int[] array) {
15008         StringBuffer buf = new StringBuffer(128);
15009         buf.append('[');
15010         if (array != null) {
15011             for (int i=0; i<array.length; i++) {
15012                 if (i > 0) buf.append(", ");
15013                 buf.append(array[i]);
15014             }
15015         }
15016         buf.append(']');
15017         return buf.toString();
15018     }
15019
15020     static class DumpState {
15021         public static final int DUMP_LIBS = 1 << 0;
15022         public static final int DUMP_FEATURES = 1 << 1;
15023         public static final int DUMP_RESOLVERS = 1 << 2;
15024         public static final int DUMP_PERMISSIONS = 1 << 3;
15025         public static final int DUMP_PACKAGES = 1 << 4;
15026         public static final int DUMP_SHARED_USERS = 1 << 5;
15027         public static final int DUMP_MESSAGES = 1 << 6;
15028         public static final int DUMP_PROVIDERS = 1 << 7;
15029         public static final int DUMP_VERIFIERS = 1 << 8;
15030         public static final int DUMP_PREFERRED = 1 << 9;
15031         public static final int DUMP_PREFERRED_XML = 1 << 10;
15032         public static final int DUMP_KEYSETS = 1 << 11;
15033         public static final int DUMP_VERSION = 1 << 12;
15034         public static final int DUMP_INSTALLS = 1 << 13;
15035         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14;
15036         public static final int DUMP_DOMAIN_PREFERRED = 1 << 15;
15037
15038         public static final int OPTION_SHOW_FILTERS = 1 << 0;
15039
15040         private int mTypes;
15041
15042         private int mOptions;
15043
15044         private boolean mTitlePrinted;
15045
15046         private SharedUserSetting mSharedUser;
15047
15048         public boolean isDumping(int type) {
15049             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
15050                 return true;
15051             }
15052
15053             return (mTypes & type) != 0;
15054         }
15055
15056         public void setDump(int type) {
15057             mTypes |= type;
15058         }
15059
15060         public boolean isOptionEnabled(int option) {
15061             return (mOptions & option) != 0;
15062         }
15063
15064         public void setOptionEnabled(int option) {
15065             mOptions |= option;
15066         }
15067
15068         public boolean onTitlePrinted() {
15069             final boolean printed = mTitlePrinted;
15070             mTitlePrinted = true;
15071             return printed;
15072         }
15073
15074         public boolean getTitlePrinted() {
15075             return mTitlePrinted;
15076         }
15077
15078         public void setTitlePrinted(boolean enabled) {
15079             mTitlePrinted = enabled;
15080         }
15081
15082         public SharedUserSetting getSharedUser() {
15083             return mSharedUser;
15084         }
15085
15086         public void setSharedUser(SharedUserSetting user) {
15087             mSharedUser = user;
15088         }
15089     }
15090
15091     @Override
15092     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15093         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
15094                 != PackageManager.PERMISSION_GRANTED) {
15095             pw.println("Permission Denial: can't dump ActivityManager from from pid="
15096                     + Binder.getCallingPid()
15097                     + ", uid=" + Binder.getCallingUid()
15098                     + " without permission "
15099                     + android.Manifest.permission.DUMP);
15100             return;
15101         }
15102
15103         DumpState dumpState = new DumpState();
15104         boolean fullPreferred = false;
15105         boolean checkin = false;
15106
15107         String packageName = null;
15108         ArraySet<String> permissionNames = null;
15109
15110         int opti = 0;
15111         while (opti < args.length) {
15112             String opt = args[opti];
15113             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15114                 break;
15115             }
15116             opti++;
15117
15118             if ("-a".equals(opt)) {
15119                 // Right now we only know how to print all.
15120             } else if ("-h".equals(opt)) {
15121                 pw.println("Package manager dump options:");
15122                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
15123                 pw.println("    --checkin: dump for a checkin");
15124                 pw.println("    -f: print details of intent filters");
15125                 pw.println("    -h: print this help");
15126                 pw.println("  cmd may be one of:");
15127                 pw.println("    l[ibraries]: list known shared libraries");
15128                 pw.println("    f[ibraries]: list device features");
15129                 pw.println("    k[eysets]: print known keysets");
15130                 pw.println("    r[esolvers]: dump intent resolvers");
15131                 pw.println("    perm[issions]: dump permissions");
15132                 pw.println("    permission [name ...]: dump declaration and use of given permission");
15133                 pw.println("    pref[erred]: print preferred package settings");
15134                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
15135                 pw.println("    prov[iders]: dump content providers");
15136                 pw.println("    p[ackages]: dump installed packages");
15137                 pw.println("    s[hared-users]: dump shared user IDs");
15138                 pw.println("    m[essages]: print collected runtime messages");
15139                 pw.println("    v[erifiers]: print package verifier info");
15140                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
15141                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
15142                 pw.println("    version: print database version info");
15143                 pw.println("    write: write current settings now");
15144                 pw.println("    installs: details about install sessions");
15145                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
15146                 pw.println("    <package.name>: info about given package");
15147                 return;
15148             } else if ("--checkin".equals(opt)) {
15149                 checkin = true;
15150             } else if ("-f".equals(opt)) {
15151                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15152             } else {
15153                 pw.println("Unknown argument: " + opt + "; use -h for help");
15154             }
15155         }
15156
15157         // Is the caller requesting to dump a particular piece of data?
15158         if (opti < args.length) {
15159             String cmd = args[opti];
15160             opti++;
15161             // Is this a package name?
15162             if ("android".equals(cmd) || cmd.contains(".")) {
15163                 packageName = cmd;
15164                 // When dumping a single package, we always dump all of its
15165                 // filter information since the amount of data will be reasonable.
15166                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15167             } else if ("check-permission".equals(cmd)) {
15168                 if (opti >= args.length) {
15169                     pw.println("Error: check-permission missing permission argument");
15170                     return;
15171                 }
15172                 String perm = args[opti];
15173                 opti++;
15174                 if (opti >= args.length) {
15175                     pw.println("Error: check-permission missing package argument");
15176                     return;
15177                 }
15178                 String pkg = args[opti];
15179                 opti++;
15180                 int user = UserHandle.getUserId(Binder.getCallingUid());
15181                 if (opti < args.length) {
15182                     try {
15183                         user = Integer.parseInt(args[opti]);
15184                     } catch (NumberFormatException e) {
15185                         pw.println("Error: check-permission user argument is not a number: "
15186                                 + args[opti]);
15187                         return;
15188                     }
15189                 }
15190                 pw.println(checkPermission(perm, pkg, user));
15191                 return;
15192             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
15193                 dumpState.setDump(DumpState.DUMP_LIBS);
15194             } else if ("f".equals(cmd) || "features".equals(cmd)) {
15195                 dumpState.setDump(DumpState.DUMP_FEATURES);
15196             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
15197                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
15198             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
15199                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
15200             } else if ("permission".equals(cmd)) {
15201                 if (opti >= args.length) {
15202                     pw.println("Error: permission requires permission name");
15203                     return;
15204                 }
15205                 permissionNames = new ArraySet<>();
15206                 while (opti < args.length) {
15207                     permissionNames.add(args[opti]);
15208                     opti++;
15209                 }
15210                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
15211                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
15212             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
15213                 dumpState.setDump(DumpState.DUMP_PREFERRED);
15214             } else if ("preferred-xml".equals(cmd)) {
15215                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
15216                 if (opti < args.length && "--full".equals(args[opti])) {
15217                     fullPreferred = true;
15218                     opti++;
15219                 }
15220             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
15221                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
15222             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
15223                 dumpState.setDump(DumpState.DUMP_PACKAGES);
15224             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
15225                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
15226             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
15227                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
15228             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
15229                 dumpState.setDump(DumpState.DUMP_MESSAGES);
15230             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
15231                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
15232             } else if ("i".equals(cmd) || "ifv".equals(cmd)
15233                     || "intent-filter-verifiers".equals(cmd)) {
15234                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
15235             } else if ("version".equals(cmd)) {
15236                 dumpState.setDump(DumpState.DUMP_VERSION);
15237             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
15238                 dumpState.setDump(DumpState.DUMP_KEYSETS);
15239             } else if ("installs".equals(cmd)) {
15240                 dumpState.setDump(DumpState.DUMP_INSTALLS);
15241             } else if ("write".equals(cmd)) {
15242                 synchronized (mPackages) {
15243                     mSettings.writeLPr();
15244                     pw.println("Settings written.");
15245                     return;
15246                 }
15247             }
15248         }
15249
15250         if (checkin) {
15251             pw.println("vers,1");
15252         }
15253
15254         // reader
15255         synchronized (mPackages) {
15256             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
15257                 if (!checkin) {
15258                     if (dumpState.onTitlePrinted())
15259                         pw.println();
15260                     pw.println("Database versions:");
15261                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
15262                 }
15263             }
15264
15265             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
15266                 if (!checkin) {
15267                     if (dumpState.onTitlePrinted())
15268                         pw.println();
15269                     pw.println("Verifiers:");
15270                     pw.print("  Required: ");
15271                     pw.print(mRequiredVerifierPackage);
15272                     pw.print(" (uid=");
15273                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
15274                     pw.println(")");
15275                 } else if (mRequiredVerifierPackage != null) {
15276                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
15277                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
15278                 }
15279             }
15280
15281             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
15282                     packageName == null) {
15283                 if (mIntentFilterVerifierComponent != null) {
15284                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
15285                     if (!checkin) {
15286                         if (dumpState.onTitlePrinted())
15287                             pw.println();
15288                         pw.println("Intent Filter Verifier:");
15289                         pw.print("  Using: ");
15290                         pw.print(verifierPackageName);
15291                         pw.print(" (uid=");
15292                         pw.print(getPackageUid(verifierPackageName, 0));
15293                         pw.println(")");
15294                     } else if (verifierPackageName != null) {
15295                         pw.print("ifv,"); pw.print(verifierPackageName);
15296                         pw.print(","); pw.println(getPackageUid(verifierPackageName, 0));
15297                     }
15298                 } else {
15299                     pw.println();
15300                     pw.println("No Intent Filter Verifier available!");
15301                 }
15302             }
15303
15304             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
15305                 boolean printedHeader = false;
15306                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
15307                 while (it.hasNext()) {
15308                     String name = it.next();
15309                     SharedLibraryEntry ent = mSharedLibraries.get(name);
15310                     if (!checkin) {
15311                         if (!printedHeader) {
15312                             if (dumpState.onTitlePrinted())
15313                                 pw.println();
15314                             pw.println("Libraries:");
15315                             printedHeader = true;
15316                         }
15317                         pw.print("  ");
15318                     } else {
15319                         pw.print("lib,");
15320                     }
15321                     pw.print(name);
15322                     if (!checkin) {
15323                         pw.print(" -> ");
15324                     }
15325                     if (ent.path != null) {
15326                         if (!checkin) {
15327                             pw.print("(jar) ");
15328                             pw.print(ent.path);
15329                         } else {
15330                             pw.print(",jar,");
15331                             pw.print(ent.path);
15332                         }
15333                     } else {
15334                         if (!checkin) {
15335                             pw.print("(apk) ");
15336                             pw.print(ent.apk);
15337                         } else {
15338                             pw.print(",apk,");
15339                             pw.print(ent.apk);
15340                         }
15341                     }
15342                     pw.println();
15343                 }
15344             }
15345
15346             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
15347                 if (dumpState.onTitlePrinted())
15348                     pw.println();
15349                 if (!checkin) {
15350                     pw.println("Features:");
15351                 }
15352                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
15353                 while (it.hasNext()) {
15354                     String name = it.next();
15355                     if (!checkin) {
15356                         pw.print("  ");
15357                     } else {
15358                         pw.print("feat,");
15359                     }
15360                     pw.println(name);
15361                 }
15362             }
15363
15364             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
15365                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
15366                         : "Activity Resolver Table:", "  ", packageName,
15367                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15368                     dumpState.setTitlePrinted(true);
15369                 }
15370                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
15371                         : "Receiver Resolver Table:", "  ", packageName,
15372                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15373                     dumpState.setTitlePrinted(true);
15374                 }
15375                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
15376                         : "Service Resolver Table:", "  ", packageName,
15377                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15378                     dumpState.setTitlePrinted(true);
15379                 }
15380                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
15381                         : "Provider Resolver Table:", "  ", packageName,
15382                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15383                     dumpState.setTitlePrinted(true);
15384                 }
15385             }
15386
15387             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
15388                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15389                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15390                     int user = mSettings.mPreferredActivities.keyAt(i);
15391                     if (pir.dump(pw,
15392                             dumpState.getTitlePrinted()
15393                                 ? "\nPreferred Activities User " + user + ":"
15394                                 : "Preferred Activities User " + user + ":", "  ",
15395                             packageName, true, false)) {
15396                         dumpState.setTitlePrinted(true);
15397                     }
15398                 }
15399             }
15400
15401             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
15402                 pw.flush();
15403                 FileOutputStream fout = new FileOutputStream(fd);
15404                 BufferedOutputStream str = new BufferedOutputStream(fout);
15405                 XmlSerializer serializer = new FastXmlSerializer();
15406                 try {
15407                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
15408                     serializer.startDocument(null, true);
15409                     serializer.setFeature(
15410                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
15411                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
15412                     serializer.endDocument();
15413                     serializer.flush();
15414                 } catch (IllegalArgumentException e) {
15415                     pw.println("Failed writing: " + e);
15416                 } catch (IllegalStateException e) {
15417                     pw.println("Failed writing: " + e);
15418                 } catch (IOException e) {
15419                     pw.println("Failed writing: " + e);
15420                 }
15421             }
15422
15423             if (!checkin
15424                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
15425                     && packageName == null) {
15426                 pw.println();
15427                 int count = mSettings.mPackages.size();
15428                 if (count == 0) {
15429                     pw.println("No applications!");
15430                     pw.println();
15431                 } else {
15432                     final String prefix = "  ";
15433                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
15434                     if (allPackageSettings.size() == 0) {
15435                         pw.println("No domain preferred apps!");
15436                         pw.println();
15437                     } else {
15438                         pw.println("App verification status:");
15439                         pw.println();
15440                         count = 0;
15441                         for (PackageSetting ps : allPackageSettings) {
15442                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
15443                             if (ivi == null || ivi.getPackageName() == null) continue;
15444                             pw.println(prefix + "Package: " + ivi.getPackageName());
15445                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
15446                             pw.println(prefix + "Status:  " + ivi.getStatusString());
15447                             pw.println();
15448                             count++;
15449                         }
15450                         if (count == 0) {
15451                             pw.println(prefix + "No app verification established.");
15452                             pw.println();
15453                         }
15454                         for (int userId : sUserManager.getUserIds()) {
15455                             pw.println("App linkages for user " + userId + ":");
15456                             pw.println();
15457                             count = 0;
15458                             for (PackageSetting ps : allPackageSettings) {
15459                                 final long status = ps.getDomainVerificationStatusForUser(userId);
15460                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
15461                                     continue;
15462                                 }
15463                                 pw.println(prefix + "Package: " + ps.name);
15464                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
15465                                 String statusStr = IntentFilterVerificationInfo.
15466                                         getStatusStringFromValue(status);
15467                                 pw.println(prefix + "Status:  " + statusStr);
15468                                 pw.println();
15469                                 count++;
15470                             }
15471                             if (count == 0) {
15472                                 pw.println(prefix + "No configured app linkages.");
15473                                 pw.println();
15474                             }
15475                         }
15476                     }
15477                 }
15478             }
15479
15480             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
15481                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
15482                 if (packageName == null && permissionNames == null) {
15483                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
15484                         if (iperm == 0) {
15485                             if (dumpState.onTitlePrinted())
15486                                 pw.println();
15487                             pw.println("AppOp Permissions:");
15488                         }
15489                         pw.print("  AppOp Permission ");
15490                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
15491                         pw.println(":");
15492                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
15493                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
15494                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
15495                         }
15496                     }
15497                 }
15498             }
15499
15500             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
15501                 boolean printedSomething = false;
15502                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
15503                     if (packageName != null && !packageName.equals(p.info.packageName)) {
15504                         continue;
15505                     }
15506                     if (!printedSomething) {
15507                         if (dumpState.onTitlePrinted())
15508                             pw.println();
15509                         pw.println("Registered ContentProviders:");
15510                         printedSomething = true;
15511                     }
15512                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
15513                     pw.print("    "); pw.println(p.toString());
15514                 }
15515                 printedSomething = false;
15516                 for (Map.Entry<String, PackageParser.Provider> entry :
15517                         mProvidersByAuthority.entrySet()) {
15518                     PackageParser.Provider p = entry.getValue();
15519                     if (packageName != null && !packageName.equals(p.info.packageName)) {
15520                         continue;
15521                     }
15522                     if (!printedSomething) {
15523                         if (dumpState.onTitlePrinted())
15524                             pw.println();
15525                         pw.println("ContentProvider Authorities:");
15526                         printedSomething = true;
15527                     }
15528                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
15529                     pw.print("    "); pw.println(p.toString());
15530                     if (p.info != null && p.info.applicationInfo != null) {
15531                         final String appInfo = p.info.applicationInfo.toString();
15532                         pw.print("      applicationInfo="); pw.println(appInfo);
15533                     }
15534                 }
15535             }
15536
15537             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
15538                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
15539             }
15540
15541             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
15542                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
15543             }
15544
15545             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
15546                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
15547             }
15548
15549             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
15550                 // XXX should handle packageName != null by dumping only install data that
15551                 // the given package is involved with.
15552                 if (dumpState.onTitlePrinted()) pw.println();
15553                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
15554             }
15555
15556             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
15557                 if (dumpState.onTitlePrinted()) pw.println();
15558                 mSettings.dumpReadMessagesLPr(pw, dumpState);
15559
15560                 pw.println();
15561                 pw.println("Package warning messages:");
15562                 BufferedReader in = null;
15563                 String line = null;
15564                 try {
15565                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
15566                     while ((line = in.readLine()) != null) {
15567                         if (line.contains("ignored: updated version")) continue;
15568                         pw.println(line);
15569                     }
15570                 } catch (IOException ignored) {
15571                 } finally {
15572                     IoUtils.closeQuietly(in);
15573                 }
15574             }
15575
15576             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
15577                 BufferedReader in = null;
15578                 String line = null;
15579                 try {
15580                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
15581                     while ((line = in.readLine()) != null) {
15582                         if (line.contains("ignored: updated version")) continue;
15583                         pw.print("msg,");
15584                         pw.println(line);
15585                     }
15586                 } catch (IOException ignored) {
15587                 } finally {
15588                     IoUtils.closeQuietly(in);
15589                 }
15590             }
15591         }
15592     }
15593
15594     private String dumpDomainString(String packageName) {
15595         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName);
15596         List<IntentFilter> filters = getAllIntentFilters(packageName);
15597
15598         ArraySet<String> result = new ArraySet<>();
15599         if (iviList.size() > 0) {
15600             for (IntentFilterVerificationInfo ivi : iviList) {
15601                 for (String host : ivi.getDomains()) {
15602                     result.add(host);
15603                 }
15604             }
15605         }
15606         if (filters != null && filters.size() > 0) {
15607             for (IntentFilter filter : filters) {
15608                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
15609                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
15610                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
15611                     result.addAll(filter.getHostsList());
15612                 }
15613             }
15614         }
15615
15616         StringBuilder sb = new StringBuilder(result.size() * 16);
15617         for (String domain : result) {
15618             if (sb.length() > 0) sb.append(" ");
15619             sb.append(domain);
15620         }
15621         return sb.toString();
15622     }
15623
15624     // ------- apps on sdcard specific code -------
15625     static final boolean DEBUG_SD_INSTALL = false;
15626
15627     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
15628
15629     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
15630
15631     private boolean mMediaMounted = false;
15632
15633     static String getEncryptKey() {
15634         try {
15635             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
15636                     SD_ENCRYPTION_KEYSTORE_NAME);
15637             if (sdEncKey == null) {
15638                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
15639                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
15640                 if (sdEncKey == null) {
15641                     Slog.e(TAG, "Failed to create encryption keys");
15642                     return null;
15643                 }
15644             }
15645             return sdEncKey;
15646         } catch (NoSuchAlgorithmException nsae) {
15647             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
15648             return null;
15649         } catch (IOException ioe) {
15650             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
15651             return null;
15652         }
15653     }
15654
15655     /*
15656      * Update media status on PackageManager.
15657      */
15658     @Override
15659     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
15660         int callingUid = Binder.getCallingUid();
15661         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15662             throw new SecurityException("Media status can only be updated by the system");
15663         }
15664         // reader; this apparently protects mMediaMounted, but should probably
15665         // be a different lock in that case.
15666         synchronized (mPackages) {
15667             Log.i(TAG, "Updating external media status from "
15668                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
15669                     + (mediaStatus ? "mounted" : "unmounted"));
15670             if (DEBUG_SD_INSTALL)
15671                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
15672                         + ", mMediaMounted=" + mMediaMounted);
15673             if (mediaStatus == mMediaMounted) {
15674                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
15675                         : 0, -1);
15676                 mHandler.sendMessage(msg);
15677                 return;
15678             }
15679             mMediaMounted = mediaStatus;
15680         }
15681         // Queue up an async operation since the package installation may take a
15682         // little while.
15683         mHandler.post(new Runnable() {
15684             public void run() {
15685                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
15686             }
15687         });
15688     }
15689
15690     /**
15691      * Called by MountService when the initial ASECs to scan are available.
15692      * Should block until all the ASEC containers are finished being scanned.
15693      */
15694     public void scanAvailableAsecs() {
15695         updateExternalMediaStatusInner(true, false, false);
15696         if (mShouldRestoreconData) {
15697             SELinuxMMAC.setRestoreconDone();
15698             mShouldRestoreconData = false;
15699         }
15700     }
15701
15702     /*
15703      * Collect information of applications on external media, map them against
15704      * existing containers and update information based on current mount status.
15705      * Please note that we always have to report status if reportStatus has been
15706      * set to true especially when unloading packages.
15707      */
15708     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
15709             boolean externalStorage) {
15710         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
15711         int[] uidArr = EmptyArray.INT;
15712
15713         final String[] list = PackageHelper.getSecureContainerList();
15714         if (ArrayUtils.isEmpty(list)) {
15715             Log.i(TAG, "No secure containers found");
15716         } else {
15717             // Process list of secure containers and categorize them
15718             // as active or stale based on their package internal state.
15719
15720             // reader
15721             synchronized (mPackages) {
15722                 for (String cid : list) {
15723                     // Leave stages untouched for now; installer service owns them
15724                     if (PackageInstallerService.isStageName(cid)) continue;
15725
15726                     if (DEBUG_SD_INSTALL)
15727                         Log.i(TAG, "Processing container " + cid);
15728                     String pkgName = getAsecPackageName(cid);
15729                     if (pkgName == null) {
15730                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
15731                         continue;
15732                     }
15733                     if (DEBUG_SD_INSTALL)
15734                         Log.i(TAG, "Looking for pkg : " + pkgName);
15735
15736                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
15737                     if (ps == null) {
15738                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
15739                         continue;
15740                     }
15741
15742                     /*
15743                      * Skip packages that are not external if we're unmounting
15744                      * external storage.
15745                      */
15746                     if (externalStorage && !isMounted && !isExternal(ps)) {
15747                         continue;
15748                     }
15749
15750                     final AsecInstallArgs args = new AsecInstallArgs(cid,
15751                             getAppDexInstructionSets(ps), ps.isForwardLocked());
15752                     // The package status is changed only if the code path
15753                     // matches between settings and the container id.
15754                     if (ps.codePathString != null
15755                             && ps.codePathString.startsWith(args.getCodePath())) {
15756                         if (DEBUG_SD_INSTALL) {
15757                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
15758                                     + " at code path: " + ps.codePathString);
15759                         }
15760
15761                         // We do have a valid package installed on sdcard
15762                         processCids.put(args, ps.codePathString);
15763                         final int uid = ps.appId;
15764                         if (uid != -1) {
15765                             uidArr = ArrayUtils.appendInt(uidArr, uid);
15766                         }
15767                     } else {
15768                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
15769                                 + ps.codePathString);
15770                     }
15771                 }
15772             }
15773
15774             Arrays.sort(uidArr);
15775         }
15776
15777         // Process packages with valid entries.
15778         if (isMounted) {
15779             if (DEBUG_SD_INSTALL)
15780                 Log.i(TAG, "Loading packages");
15781             loadMediaPackages(processCids, uidArr, externalStorage);
15782             startCleaningPackages();
15783             mInstallerService.onSecureContainersAvailable();
15784         } else {
15785             if (DEBUG_SD_INSTALL)
15786                 Log.i(TAG, "Unloading packages");
15787             unloadMediaPackages(processCids, uidArr, reportStatus);
15788         }
15789     }
15790
15791     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
15792             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
15793         final int size = infos.size();
15794         final String[] packageNames = new String[size];
15795         final int[] packageUids = new int[size];
15796         for (int i = 0; i < size; i++) {
15797             final ApplicationInfo info = infos.get(i);
15798             packageNames[i] = info.packageName;
15799             packageUids[i] = info.uid;
15800         }
15801         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
15802                 finishedReceiver);
15803     }
15804
15805     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
15806             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
15807         sendResourcesChangedBroadcast(mediaStatus, replacing,
15808                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
15809     }
15810
15811     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
15812             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
15813         int size = pkgList.length;
15814         if (size > 0) {
15815             // Send broadcasts here
15816             Bundle extras = new Bundle();
15817             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
15818             if (uidArr != null) {
15819                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
15820             }
15821             if (replacing) {
15822                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
15823             }
15824             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
15825                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
15826             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
15827         }
15828     }
15829
15830    /*
15831      * Look at potentially valid container ids from processCids If package
15832      * information doesn't match the one on record or package scanning fails,
15833      * the cid is added to list of removeCids. We currently don't delete stale
15834      * containers.
15835      */
15836     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
15837             boolean externalStorage) {
15838         ArrayList<String> pkgList = new ArrayList<String>();
15839         Set<AsecInstallArgs> keys = processCids.keySet();
15840
15841         for (AsecInstallArgs args : keys) {
15842             String codePath = processCids.get(args);
15843             if (DEBUG_SD_INSTALL)
15844                 Log.i(TAG, "Loading container : " + args.cid);
15845             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15846             try {
15847                 // Make sure there are no container errors first.
15848                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
15849                     Slog.e(TAG, "Failed to mount cid : " + args.cid
15850                             + " when installing from sdcard");
15851                     continue;
15852                 }
15853                 // Check code path here.
15854                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
15855                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
15856                             + " does not match one in settings " + codePath);
15857                     continue;
15858                 }
15859                 // Parse package
15860                 int parseFlags = mDefParseFlags;
15861                 if (args.isExternalAsec()) {
15862                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
15863                 }
15864                 if (args.isFwdLocked()) {
15865                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
15866                 }
15867
15868                 synchronized (mInstallLock) {
15869                     PackageParser.Package pkg = null;
15870                     try {
15871                         pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
15872                     } catch (PackageManagerException e) {
15873                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
15874                     }
15875                     // Scan the package
15876                     if (pkg != null) {
15877                         /*
15878                          * TODO why is the lock being held? doPostInstall is
15879                          * called in other places without the lock. This needs
15880                          * to be straightened out.
15881                          */
15882                         // writer
15883                         synchronized (mPackages) {
15884                             retCode = PackageManager.INSTALL_SUCCEEDED;
15885                             pkgList.add(pkg.packageName);
15886                             // Post process args
15887                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
15888                                     pkg.applicationInfo.uid);
15889                         }
15890                     } else {
15891                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
15892                     }
15893                 }
15894
15895             } finally {
15896                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
15897                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
15898                 }
15899             }
15900         }
15901         // writer
15902         synchronized (mPackages) {
15903             // If the platform SDK has changed since the last time we booted,
15904             // we need to re-grant app permission to catch any new ones that
15905             // appear. This is really a hack, and means that apps can in some
15906             // cases get permissions that the user didn't initially explicitly
15907             // allow... it would be nice to have some better way to handle
15908             // this situation.
15909             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
15910                     : mSettings.getInternalVersion();
15911             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
15912                     : StorageManager.UUID_PRIVATE_INTERNAL;
15913
15914             int updateFlags = UPDATE_PERMISSIONS_ALL;
15915             if (ver.sdkVersion != mSdkVersion) {
15916                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
15917                         + mSdkVersion + "; regranting permissions for external");
15918                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
15919             }
15920             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
15921
15922             // Yay, everything is now upgraded
15923             ver.forceCurrent();
15924
15925             // can downgrade to reader
15926             // Persist settings
15927             mSettings.writeLPr();
15928         }
15929         // Send a broadcast to let everyone know we are done processing
15930         if (pkgList.size() > 0) {
15931             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
15932         }
15933     }
15934
15935    /*
15936      * Utility method to unload a list of specified containers
15937      */
15938     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
15939         // Just unmount all valid containers.
15940         for (AsecInstallArgs arg : cidArgs) {
15941             synchronized (mInstallLock) {
15942                 arg.doPostDeleteLI(false);
15943            }
15944        }
15945    }
15946
15947     /*
15948      * Unload packages mounted on external media. This involves deleting package
15949      * data from internal structures, sending broadcasts about diabled packages,
15950      * gc'ing to free up references, unmounting all secure containers
15951      * corresponding to packages on external media, and posting a
15952      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
15953      * that we always have to post this message if status has been requested no
15954      * matter what.
15955      */
15956     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
15957             final boolean reportStatus) {
15958         if (DEBUG_SD_INSTALL)
15959             Log.i(TAG, "unloading media packages");
15960         ArrayList<String> pkgList = new ArrayList<String>();
15961         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
15962         final Set<AsecInstallArgs> keys = processCids.keySet();
15963         for (AsecInstallArgs args : keys) {
15964             String pkgName = args.getPackageName();
15965             if (DEBUG_SD_INSTALL)
15966                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
15967             // Delete package internally
15968             PackageRemovedInfo outInfo = new PackageRemovedInfo();
15969             synchronized (mInstallLock) {
15970                 boolean res = deletePackageLI(pkgName, null, false, null, null,
15971                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
15972                 if (res) {
15973                     pkgList.add(pkgName);
15974                 } else {
15975                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
15976                     failedList.add(args);
15977                 }
15978             }
15979         }
15980
15981         // reader
15982         synchronized (mPackages) {
15983             // We didn't update the settings after removing each package;
15984             // write them now for all packages.
15985             mSettings.writeLPr();
15986         }
15987
15988         // We have to absolutely send UPDATED_MEDIA_STATUS only
15989         // after confirming that all the receivers processed the ordered
15990         // broadcast when packages get disabled, force a gc to clean things up.
15991         // and unload all the containers.
15992         if (pkgList.size() > 0) {
15993             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
15994                     new IIntentReceiver.Stub() {
15995                 public void performReceive(Intent intent, int resultCode, String data,
15996                         Bundle extras, boolean ordered, boolean sticky,
15997                         int sendingUser) throws RemoteException {
15998                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
15999                             reportStatus ? 1 : 0, 1, keys);
16000                     mHandler.sendMessage(msg);
16001                 }
16002             });
16003         } else {
16004             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
16005                     keys);
16006             mHandler.sendMessage(msg);
16007         }
16008     }
16009
16010     private void loadPrivatePackages(final VolumeInfo vol) {
16011         mHandler.post(new Runnable() {
16012             @Override
16013             public void run() {
16014                 loadPrivatePackagesInner(vol);
16015             }
16016         });
16017     }
16018
16019     private void loadPrivatePackagesInner(VolumeInfo vol) {
16020         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
16021         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
16022
16023         final VersionInfo ver;
16024         final List<PackageSetting> packages;
16025         synchronized (mPackages) {
16026             ver = mSettings.findOrCreateVersion(vol.fsUuid);
16027             packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16028         }
16029
16030         for (PackageSetting ps : packages) {
16031             synchronized (mInstallLock) {
16032                 final PackageParser.Package pkg;
16033                 try {
16034                     pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null);
16035                     loaded.add(pkg.applicationInfo);
16036                 } catch (PackageManagerException e) {
16037                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
16038                 }
16039
16040                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
16041                     deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
16042                 }
16043             }
16044         }
16045
16046         synchronized (mPackages) {
16047             int updateFlags = UPDATE_PERMISSIONS_ALL;
16048             if (ver.sdkVersion != mSdkVersion) {
16049                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16050                         + mSdkVersion + "; regranting permissions for " + vol.fsUuid);
16051                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16052             }
16053             updatePermissionsLPw(null, null, vol.fsUuid, updateFlags);
16054
16055             // Yay, everything is now upgraded
16056             ver.forceCurrent();
16057
16058             mSettings.writeLPr();
16059         }
16060
16061         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
16062         sendResourcesChangedBroadcast(true, false, loaded, null);
16063     }
16064
16065     private void unloadPrivatePackages(final VolumeInfo vol) {
16066         mHandler.post(new Runnable() {
16067             @Override
16068             public void run() {
16069                 unloadPrivatePackagesInner(vol);
16070             }
16071         });
16072     }
16073
16074     private void unloadPrivatePackagesInner(VolumeInfo vol) {
16075         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
16076         synchronized (mInstallLock) {
16077         synchronized (mPackages) {
16078             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16079             for (PackageSetting ps : packages) {
16080                 if (ps.pkg == null) continue;
16081
16082                 final ApplicationInfo info = ps.pkg.applicationInfo;
16083                 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
16084                 if (deletePackageLI(ps.name, null, false, null, null,
16085                         PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
16086                     unloaded.add(info);
16087                 } else {
16088                     Slog.w(TAG, "Failed to unload " + ps.codePath);
16089                 }
16090             }
16091
16092             mSettings.writeLPr();
16093         }
16094         }
16095
16096         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
16097         sendResourcesChangedBroadcast(false, false, unloaded, null);
16098     }
16099
16100     /**
16101      * Examine all users present on given mounted volume, and destroy data
16102      * belonging to users that are no longer valid, or whose user ID has been
16103      * recycled.
16104      */
16105     private void reconcileUsers(String volumeUuid) {
16106         final File[] files = FileUtils
16107                 .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid));
16108         for (File file : files) {
16109             if (!file.isDirectory()) continue;
16110
16111             final int userId;
16112             final UserInfo info;
16113             try {
16114                 userId = Integer.parseInt(file.getName());
16115                 info = sUserManager.getUserInfo(userId);
16116             } catch (NumberFormatException e) {
16117                 Slog.w(TAG, "Invalid user directory " + file);
16118                 continue;
16119             }
16120
16121             boolean destroyUser = false;
16122             if (info == null) {
16123                 logCriticalInfo(Log.WARN, "Destroying user directory " + file
16124                         + " because no matching user was found");
16125                 destroyUser = true;
16126             } else {
16127                 try {
16128                     UserManagerService.enforceSerialNumber(file, info.serialNumber);
16129                 } catch (IOException e) {
16130                     logCriticalInfo(Log.WARN, "Destroying user directory " + file
16131                             + " because we failed to enforce serial number: " + e);
16132                     destroyUser = true;
16133                 }
16134             }
16135
16136             if (destroyUser) {
16137                 synchronized (mInstallLock) {
16138                     mInstaller.removeUserDataDirs(volumeUuid, userId);
16139                 }
16140             }
16141         }
16142
16143         final UserManager um = mContext.getSystemService(UserManager.class);
16144         for (UserInfo user : um.getUsers()) {
16145             final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id);
16146             if (userDir.exists()) continue;
16147
16148             try {
16149                 UserManagerService.prepareUserDirectory(mContext, volumeUuid, user.id);
16150                 UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
16151             } catch (IOException e) {
16152                 Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
16153             }
16154         }
16155     }
16156
16157     /**
16158      * Examine all apps present on given mounted volume, and destroy apps that
16159      * aren't expected, either due to uninstallation or reinstallation on
16160      * another volume.
16161      */
16162     private void reconcileApps(String volumeUuid) {
16163         final File[] files = FileUtils
16164                 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
16165         for (File file : files) {
16166             final boolean isPackage = (isApkFile(file) || file.isDirectory())
16167                     && !PackageInstallerService.isStageName(file.getName());
16168             if (!isPackage) {
16169                 // Ignore entries which are not packages
16170                 continue;
16171             }
16172
16173             boolean destroyApp = false;
16174             String packageName = null;
16175             try {
16176                 final PackageLite pkg = PackageParser.parsePackageLite(file,
16177                         PackageParser.PARSE_MUST_BE_APK);
16178                 packageName = pkg.packageName;
16179
16180                 synchronized (mPackages) {
16181                     final PackageSetting ps = mSettings.mPackages.get(packageName);
16182                     if (ps == null) {
16183                         logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + "
16184                                 + volumeUuid + " because we found no install record");
16185                         destroyApp = true;
16186                     } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
16187                         logCriticalInfo(Log.WARN, "Destroying " + packageName + " on "
16188                                 + volumeUuid + " because we expected it on " + ps.volumeUuid);
16189                         destroyApp = true;
16190                     }
16191                 }
16192
16193             } catch (PackageParserException e) {
16194                 logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e);
16195                 destroyApp = true;
16196             }
16197
16198             if (destroyApp) {
16199                 synchronized (mInstallLock) {
16200                     if (packageName != null) {
16201                         removeDataDirsLI(volumeUuid, packageName);
16202                     }
16203                     if (file.isDirectory()) {
16204                         mInstaller.rmPackageDir(file.getAbsolutePath());
16205                     } else {
16206                         file.delete();
16207                     }
16208                 }
16209             }
16210         }
16211     }
16212
16213     private void unfreezePackage(String packageName) {
16214         synchronized (mPackages) {
16215             final PackageSetting ps = mSettings.mPackages.get(packageName);
16216             if (ps != null) {
16217                 ps.frozen = false;
16218             }
16219         }
16220     }
16221
16222     @Override
16223     public int movePackage(final String packageName, final String volumeUuid) {
16224         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16225
16226         final int moveId = mNextMoveId.getAndIncrement();
16227         mHandler.post(new Runnable() {
16228             @Override
16229             public void run() {
16230                 try {
16231                     movePackageInternal(packageName, volumeUuid, moveId);
16232                 } catch (PackageManagerException e) {
16233                     Slog.w(TAG, "Failed to move " + packageName, e);
16234                     mMoveCallbacks.notifyStatusChanged(moveId,
16235                             PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16236                 }
16237             }
16238         });
16239         return moveId;
16240     }
16241
16242     private void movePackageInternal(final String packageName, final String volumeUuid,
16243             final int moveId) throws PackageManagerException {
16244         final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
16245         final StorageManager storage = mContext.getSystemService(StorageManager.class);
16246         final PackageManager pm = mContext.getPackageManager();
16247
16248         final boolean currentAsec;
16249         final String currentVolumeUuid;
16250         final File codeFile;
16251         final String installerPackageName;
16252         final String packageAbiOverride;
16253         final int appId;
16254         final String seinfo;
16255         final String label;
16256
16257         // reader
16258         synchronized (mPackages) {
16259             final PackageParser.Package pkg = mPackages.get(packageName);
16260             final PackageSetting ps = mSettings.mPackages.get(packageName);
16261             if (pkg == null || ps == null) {
16262                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
16263             }
16264
16265             if (pkg.applicationInfo.isSystemApp()) {
16266                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
16267                         "Cannot move system application");
16268             }
16269
16270             if (pkg.applicationInfo.isExternalAsec()) {
16271                 currentAsec = true;
16272                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
16273             } else if (pkg.applicationInfo.isForwardLocked()) {
16274                 currentAsec = true;
16275                 currentVolumeUuid = "forward_locked";
16276             } else {
16277                 currentAsec = false;
16278                 currentVolumeUuid = ps.volumeUuid;
16279
16280                 final File probe = new File(pkg.codePath);
16281                 final File probeOat = new File(probe, "oat");
16282                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
16283                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16284                             "Move only supported for modern cluster style installs");
16285                 }
16286             }
16287
16288             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
16289                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16290                         "Package already moved to " + volumeUuid);
16291             }
16292
16293             if (ps.frozen) {
16294                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
16295                         "Failed to move already frozen package");
16296             }
16297             ps.frozen = true;
16298
16299             codeFile = new File(pkg.codePath);
16300             installerPackageName = ps.installerPackageName;
16301             packageAbiOverride = ps.cpuAbiOverrideString;
16302             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16303             seinfo = pkg.applicationInfo.seinfo;
16304             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
16305         }
16306
16307         // Now that we're guarded by frozen state, kill app during move
16308         final long token = Binder.clearCallingIdentity();
16309         try {
16310             killApplication(packageName, appId, "move pkg");
16311         } finally {
16312             Binder.restoreCallingIdentity(token);
16313         }
16314
16315         final Bundle extras = new Bundle();
16316         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
16317         extras.putString(Intent.EXTRA_TITLE, label);
16318         mMoveCallbacks.notifyCreated(moveId, extras);
16319
16320         int installFlags;
16321         final boolean moveCompleteApp;
16322         final File measurePath;
16323
16324         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
16325             installFlags = INSTALL_INTERNAL;
16326             moveCompleteApp = !currentAsec;
16327             measurePath = Environment.getDataAppDirectory(volumeUuid);
16328         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
16329             installFlags = INSTALL_EXTERNAL;
16330             moveCompleteApp = false;
16331             measurePath = storage.getPrimaryPhysicalVolume().getPath();
16332         } else {
16333             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
16334             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
16335                     || !volume.isMountedWritable()) {
16336                 unfreezePackage(packageName);
16337                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16338                         "Move location not mounted private volume");
16339             }
16340
16341             Preconditions.checkState(!currentAsec);
16342
16343             installFlags = INSTALL_INTERNAL;
16344             moveCompleteApp = true;
16345             measurePath = Environment.getDataAppDirectory(volumeUuid);
16346         }
16347
16348         final PackageStats stats = new PackageStats(null, -1);
16349         synchronized (mInstaller) {
16350             if (!getPackageSizeInfoLI(packageName, -1, stats)) {
16351                 unfreezePackage(packageName);
16352                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16353                         "Failed to measure package size");
16354             }
16355         }
16356
16357         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
16358                 + stats.dataSize);
16359
16360         final long startFreeBytes = measurePath.getFreeSpace();
16361         final long sizeBytes;
16362         if (moveCompleteApp) {
16363             sizeBytes = stats.codeSize + stats.dataSize;
16364         } else {
16365             sizeBytes = stats.codeSize;
16366         }
16367
16368         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
16369             unfreezePackage(packageName);
16370             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16371                     "Not enough free space to move");
16372         }
16373
16374         mMoveCallbacks.notifyStatusChanged(moveId, 10);
16375
16376         final CountDownLatch installedLatch = new CountDownLatch(1);
16377         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
16378             @Override
16379             public void onUserActionRequired(Intent intent) throws RemoteException {
16380                 throw new IllegalStateException();
16381             }
16382
16383             @Override
16384             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
16385                     Bundle extras) throws RemoteException {
16386                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
16387                         + PackageManager.installStatusToString(returnCode, msg));
16388
16389                 installedLatch.countDown();
16390
16391                 // Regardless of success or failure of the move operation,
16392                 // always unfreeze the package
16393                 unfreezePackage(packageName);
16394
16395                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
16396                 switch (status) {
16397                     case PackageInstaller.STATUS_SUCCESS:
16398                         mMoveCallbacks.notifyStatusChanged(moveId,
16399                                 PackageManager.MOVE_SUCCEEDED);
16400                         break;
16401                     case PackageInstaller.STATUS_FAILURE_STORAGE:
16402                         mMoveCallbacks.notifyStatusChanged(moveId,
16403                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
16404                         break;
16405                     default:
16406                         mMoveCallbacks.notifyStatusChanged(moveId,
16407                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16408                         break;
16409                 }
16410             }
16411         };
16412
16413         final MoveInfo move;
16414         if (moveCompleteApp) {
16415             // Kick off a thread to report progress estimates
16416             new Thread() {
16417                 @Override
16418                 public void run() {
16419                     while (true) {
16420                         try {
16421                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
16422                                 break;
16423                             }
16424                         } catch (InterruptedException ignored) {
16425                         }
16426
16427                         final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
16428                         final int progress = 10 + (int) MathUtils.constrain(
16429                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
16430                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
16431                     }
16432                 }
16433             }.start();
16434
16435             final String dataAppName = codeFile.getName();
16436             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
16437                     dataAppName, appId, seinfo);
16438         } else {
16439             move = null;
16440         }
16441
16442         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
16443
16444         final Message msg = mHandler.obtainMessage(INIT_COPY);
16445         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
16446         msg.obj = new InstallParams(origin, move, installObserver, installFlags,
16447                 installerPackageName, volumeUuid, null, user, packageAbiOverride, null);
16448         mHandler.sendMessage(msg);
16449     }
16450
16451     @Override
16452     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
16453         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16454
16455         final int realMoveId = mNextMoveId.getAndIncrement();
16456         final Bundle extras = new Bundle();
16457         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
16458         mMoveCallbacks.notifyCreated(realMoveId, extras);
16459
16460         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
16461             @Override
16462             public void onCreated(int moveId, Bundle extras) {
16463                 // Ignored
16464             }
16465
16466             @Override
16467             public void onStatusChanged(int moveId, int status, long estMillis) {
16468                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
16469             }
16470         };
16471
16472         final StorageManager storage = mContext.getSystemService(StorageManager.class);
16473         storage.setPrimaryStorageUuid(volumeUuid, callback);
16474         return realMoveId;
16475     }
16476
16477     @Override
16478     public int getMoveStatus(int moveId) {
16479         mContext.enforceCallingOrSelfPermission(
16480                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16481         return mMoveCallbacks.mLastStatus.get(moveId);
16482     }
16483
16484     @Override
16485     public void registerMoveCallback(IPackageMoveObserver callback) {
16486         mContext.enforceCallingOrSelfPermission(
16487                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16488         mMoveCallbacks.register(callback);
16489     }
16490
16491     @Override
16492     public void unregisterMoveCallback(IPackageMoveObserver callback) {
16493         mContext.enforceCallingOrSelfPermission(
16494                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16495         mMoveCallbacks.unregister(callback);
16496     }
16497
16498     @Override
16499     public boolean setInstallLocation(int loc) {
16500         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
16501                 null);
16502         if (getInstallLocation() == loc) {
16503             return true;
16504         }
16505         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
16506                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
16507             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
16508                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
16509             return true;
16510         }
16511         return false;
16512    }
16513
16514     @Override
16515     public int getInstallLocation() {
16516         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
16517                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
16518                 PackageHelper.APP_INSTALL_AUTO);
16519     }
16520
16521     /** Called by UserManagerService */
16522     void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
16523         mDirtyUsers.remove(userHandle);
16524         mSettings.removeUserLPw(userHandle);
16525         mPendingBroadcasts.remove(userHandle);
16526         if (mInstaller != null) {
16527             // Technically, we shouldn't be doing this with the package lock
16528             // held.  However, this is very rare, and there is already so much
16529             // other disk I/O going on, that we'll let it slide for now.
16530             final StorageManager storage = mContext.getSystemService(StorageManager.class);
16531             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
16532                 final String volumeUuid = vol.getFsUuid();
16533                 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
16534                 mInstaller.removeUserDataDirs(volumeUuid, userHandle);
16535             }
16536         }
16537         mUserNeedsBadging.delete(userHandle);
16538         removeUnusedPackagesLILPw(userManager, userHandle);
16539     }
16540
16541     /**
16542      * We're removing userHandle and would like to remove any downloaded packages
16543      * that are no longer in use by any other user.
16544      * @param userHandle the user being removed
16545      */
16546     private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
16547         final boolean DEBUG_CLEAN_APKS = false;
16548         int [] users = userManager.getUserIdsLPr();
16549         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
16550         while (psit.hasNext()) {
16551             PackageSetting ps = psit.next();
16552             if (ps.pkg == null) {
16553                 continue;
16554             }
16555             final String packageName = ps.pkg.packageName;
16556             // Skip over if system app
16557             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16558                 continue;
16559             }
16560             if (DEBUG_CLEAN_APKS) {
16561                 Slog.i(TAG, "Checking package " + packageName);
16562             }
16563             boolean keep = false;
16564             for (int i = 0; i < users.length; i++) {
16565                 if (users[i] != userHandle && ps.getInstalled(users[i])) {
16566                     keep = true;
16567                     if (DEBUG_CLEAN_APKS) {
16568                         Slog.i(TAG, "  Keeping package " + packageName + " for user "
16569                                 + users[i]);
16570                     }
16571                     break;
16572                 }
16573             }
16574             if (!keep) {
16575                 if (DEBUG_CLEAN_APKS) {
16576                     Slog.i(TAG, "  Removing package " + packageName);
16577                 }
16578                 mHandler.post(new Runnable() {
16579                     public void run() {
16580                         deletePackageX(packageName, userHandle, 0);
16581                     } //end run
16582                 });
16583             }
16584         }
16585     }
16586
16587     /** Called by UserManagerService */
16588     void createNewUserLILPw(int userHandle) {
16589         if (mInstaller != null) {
16590             mInstaller.createUserConfig(userHandle);
16591             mSettings.createNewUserLILPw(this, mInstaller, userHandle);
16592             applyFactoryDefaultBrowserLPw(userHandle);
16593             primeDomainVerificationsLPw(userHandle);
16594         }
16595     }
16596
16597     void newUserCreated(final int userHandle) {
16598         mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
16599     }
16600
16601     @Override
16602     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
16603         mContext.enforceCallingOrSelfPermission(
16604                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16605                 "Only package verification agents can read the verifier device identity");
16606
16607         synchronized (mPackages) {
16608             return mSettings.getVerifierDeviceIdentityLPw();
16609         }
16610     }
16611
16612     @Override
16613     public void setPermissionEnforced(String permission, boolean enforced) {
16614         // TODO: Now that we no longer change GID for storage, this should to away.
16615         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
16616                 "setPermissionEnforced");
16617         if (READ_EXTERNAL_STORAGE.equals(permission)) {
16618             synchronized (mPackages) {
16619                 if (mSettings.mReadExternalStorageEnforced == null
16620                         || mSettings.mReadExternalStorageEnforced != enforced) {
16621                     mSettings.mReadExternalStorageEnforced = enforced;
16622                     mSettings.writeLPr();
16623                 }
16624             }
16625             // kill any non-foreground processes so we restart them and
16626             // grant/revoke the GID.
16627             final IActivityManager am = ActivityManagerNative.getDefault();
16628             if (am != null) {
16629                 final long token = Binder.clearCallingIdentity();
16630                 try {
16631                     am.killProcessesBelowForeground("setPermissionEnforcement");
16632                 } catch (RemoteException e) {
16633                 } finally {
16634                     Binder.restoreCallingIdentity(token);
16635                 }
16636             }
16637         } else {
16638             throw new IllegalArgumentException("No selective enforcement for " + permission);
16639         }
16640     }
16641
16642     @Override
16643     @Deprecated
16644     public boolean isPermissionEnforced(String permission) {
16645         return true;
16646     }
16647
16648     @Override
16649     public boolean isStorageLow() {
16650         final long token = Binder.clearCallingIdentity();
16651         try {
16652             final DeviceStorageMonitorInternal
16653                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
16654             if (dsm != null) {
16655                 return dsm.isMemoryLow();
16656             } else {
16657                 return false;
16658             }
16659         } finally {
16660             Binder.restoreCallingIdentity(token);
16661         }
16662     }
16663
16664     @Override
16665     public IPackageInstaller getPackageInstaller() {
16666         return mInstallerService;
16667     }
16668
16669     private boolean userNeedsBadging(int userId) {
16670         int index = mUserNeedsBadging.indexOfKey(userId);
16671         if (index < 0) {
16672             final UserInfo userInfo;
16673             final long token = Binder.clearCallingIdentity();
16674             try {
16675                 userInfo = sUserManager.getUserInfo(userId);
16676             } finally {
16677                 Binder.restoreCallingIdentity(token);
16678             }
16679             final boolean b;
16680             if (userInfo != null && userInfo.isManagedProfile()) {
16681                 b = true;
16682             } else {
16683                 b = false;
16684             }
16685             mUserNeedsBadging.put(userId, b);
16686             return b;
16687         }
16688         return mUserNeedsBadging.valueAt(index);
16689     }
16690
16691     @Override
16692     public KeySet getKeySetByAlias(String packageName, String alias) {
16693         if (packageName == null || alias == null) {
16694             return null;
16695         }
16696         synchronized(mPackages) {
16697             final PackageParser.Package pkg = mPackages.get(packageName);
16698             if (pkg == null) {
16699                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16700                 throw new IllegalArgumentException("Unknown package: " + packageName);
16701             }
16702             KeySetManagerService ksms = mSettings.mKeySetManagerService;
16703             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
16704         }
16705     }
16706
16707     @Override
16708     public KeySet getSigningKeySet(String packageName) {
16709         if (packageName == null) {
16710             return null;
16711         }
16712         synchronized(mPackages) {
16713             final PackageParser.Package pkg = mPackages.get(packageName);
16714             if (pkg == null) {
16715                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16716                 throw new IllegalArgumentException("Unknown package: " + packageName);
16717             }
16718             if (pkg.applicationInfo.uid != Binder.getCallingUid()
16719                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
16720                 throw new SecurityException("May not access signing KeySet of other apps.");
16721             }
16722             KeySetManagerService ksms = mSettings.mKeySetManagerService;
16723             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
16724         }
16725     }
16726
16727     @Override
16728     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
16729         if (packageName == null || ks == null) {
16730             return false;
16731         }
16732         synchronized(mPackages) {
16733             final PackageParser.Package pkg = mPackages.get(packageName);
16734             if (pkg == null) {
16735                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16736                 throw new IllegalArgumentException("Unknown package: " + packageName);
16737             }
16738             IBinder ksh = ks.getToken();
16739             if (ksh instanceof KeySetHandle) {
16740                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
16741                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
16742             }
16743             return false;
16744         }
16745     }
16746
16747     @Override
16748     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
16749         if (packageName == null || ks == null) {
16750             return false;
16751         }
16752         synchronized(mPackages) {
16753             final PackageParser.Package pkg = mPackages.get(packageName);
16754             if (pkg == null) {
16755                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
16756                 throw new IllegalArgumentException("Unknown package: " + packageName);
16757             }
16758             IBinder ksh = ks.getToken();
16759             if (ksh instanceof KeySetHandle) {
16760                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
16761                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
16762             }
16763             return false;
16764         }
16765     }
16766
16767     public void getUsageStatsIfNoPackageUsageInfo() {
16768         if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
16769             UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
16770             if (usm == null) {
16771                 throw new IllegalStateException("UsageStatsManager must be initialized");
16772             }
16773             long now = System.currentTimeMillis();
16774             Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
16775             for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
16776                 String packageName = entry.getKey();
16777                 PackageParser.Package pkg = mPackages.get(packageName);
16778                 if (pkg == null) {
16779                     continue;
16780                 }
16781                 UsageStats usage = entry.getValue();
16782                 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
16783                 mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
16784             }
16785         }
16786     }
16787
16788     /**
16789      * Check and throw if the given before/after packages would be considered a
16790      * downgrade.
16791      */
16792     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
16793             throws PackageManagerException {
16794         if (after.versionCode < before.mVersionCode) {
16795             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
16796                     "Update version code " + after.versionCode + " is older than current "
16797                     + before.mVersionCode);
16798         } else if (after.versionCode == before.mVersionCode) {
16799             if (after.baseRevisionCode < before.baseRevisionCode) {
16800                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
16801                         "Update base revision code " + after.baseRevisionCode
16802                         + " is older than current " + before.baseRevisionCode);
16803             }
16804
16805             if (!ArrayUtils.isEmpty(after.splitNames)) {
16806                 for (int i = 0; i < after.splitNames.length; i++) {
16807                     final String splitName = after.splitNames[i];
16808                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
16809                     if (j != -1) {
16810                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
16811                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
16812                                     "Update split " + splitName + " revision code "
16813                                     + after.splitRevisionCodes[i] + " is older than current "
16814                                     + before.splitRevisionCodes[j]);
16815                         }
16816                     }
16817                 }
16818             }
16819         }
16820     }
16821
16822     private static class MoveCallbacks extends Handler {
16823         private static final int MSG_CREATED = 1;
16824         private static final int MSG_STATUS_CHANGED = 2;
16825
16826         private final RemoteCallbackList<IPackageMoveObserver>
16827                 mCallbacks = new RemoteCallbackList<>();
16828
16829         private final SparseIntArray mLastStatus = new SparseIntArray();
16830
16831         public MoveCallbacks(Looper looper) {
16832             super(looper);
16833         }
16834
16835         public void register(IPackageMoveObserver callback) {
16836             mCallbacks.register(callback);
16837         }
16838
16839         public void unregister(IPackageMoveObserver callback) {
16840             mCallbacks.unregister(callback);
16841         }
16842
16843         @Override
16844         public void handleMessage(Message msg) {
16845             final SomeArgs args = (SomeArgs) msg.obj;
16846             final int n = mCallbacks.beginBroadcast();
16847             for (int i = 0; i < n; i++) {
16848                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
16849                 try {
16850                     invokeCallback(callback, msg.what, args);
16851                 } catch (RemoteException ignored) {
16852                 }
16853             }
16854             mCallbacks.finishBroadcast();
16855             args.recycle();
16856         }
16857
16858         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
16859                 throws RemoteException {
16860             switch (what) {
16861                 case MSG_CREATED: {
16862                     callback.onCreated(args.argi1, (Bundle) args.arg2);
16863                     break;
16864                 }
16865                 case MSG_STATUS_CHANGED: {
16866                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
16867                     break;
16868                 }
16869             }
16870         }
16871
16872         private void notifyCreated(int moveId, Bundle extras) {
16873             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
16874
16875             final SomeArgs args = SomeArgs.obtain();
16876             args.argi1 = moveId;
16877             args.arg2 = extras;
16878             obtainMessage(MSG_CREATED, args).sendToTarget();
16879         }
16880
16881         private void notifyStatusChanged(int moveId, int status) {
16882             notifyStatusChanged(moveId, status, -1);
16883         }
16884
16885         private void notifyStatusChanged(int moveId, int status, long estMillis) {
16886             Slog.v(TAG, "Move " + moveId + " status " + status);
16887
16888             final SomeArgs args = SomeArgs.obtain();
16889             args.argi1 = moveId;
16890             args.argi2 = status;
16891             args.arg3 = estMillis;
16892             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
16893
16894             synchronized (mLastStatus) {
16895                 mLastStatus.put(moveId, status);
16896             }
16897         }
16898     }
16899
16900     private final class OnPermissionChangeListeners extends Handler {
16901         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
16902
16903         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
16904                 new RemoteCallbackList<>();
16905
16906         public OnPermissionChangeListeners(Looper looper) {
16907             super(looper);
16908         }
16909
16910         @Override
16911         public void handleMessage(Message msg) {
16912             switch (msg.what) {
16913                 case MSG_ON_PERMISSIONS_CHANGED: {
16914                     final int uid = msg.arg1;
16915                     handleOnPermissionsChanged(uid);
16916                 } break;
16917             }
16918         }
16919
16920         public void addListenerLocked(IOnPermissionsChangeListener listener) {
16921             mPermissionListeners.register(listener);
16922
16923         }
16924
16925         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
16926             mPermissionListeners.unregister(listener);
16927         }
16928
16929         public void onPermissionsChanged(int uid) {
16930             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
16931                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
16932             }
16933         }
16934
16935         private void handleOnPermissionsChanged(int uid) {
16936             final int count = mPermissionListeners.beginBroadcast();
16937             try {
16938                 for (int i = 0; i < count; i++) {
16939                     IOnPermissionsChangeListener callback = mPermissionListeners
16940                             .getBroadcastItem(i);
16941                     try {
16942                         callback.onPermissionsChanged(uid);
16943                     } catch (RemoteException e) {
16944                         Log.e(TAG, "Permission listener is dead", e);
16945                     }
16946                 }
16947             } finally {
16948                 mPermissionListeners.finishBroadcast();
16949             }
16950         }
16951     }
16952
16953     private class PackageManagerInternalImpl extends PackageManagerInternal {
16954         @Override
16955         public void setLocationPackagesProvider(PackagesProvider provider) {
16956             synchronized (mPackages) {
16957                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
16958             }
16959         }
16960
16961         @Override
16962         public void setImePackagesProvider(PackagesProvider provider) {
16963             synchronized (mPackages) {
16964                 mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
16965             }
16966         }
16967
16968         @Override
16969         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
16970             synchronized (mPackages) {
16971                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
16972             }
16973         }
16974
16975         @Override
16976         public void setSmsAppPackagesProvider(PackagesProvider provider) {
16977             synchronized (mPackages) {
16978                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
16979             }
16980         }
16981
16982         @Override
16983         public void setDialerAppPackagesProvider(PackagesProvider provider) {
16984             synchronized (mPackages) {
16985                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
16986             }
16987         }
16988
16989         @Override
16990         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
16991             synchronized (mPackages) {
16992                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
16993             }
16994         }
16995
16996         @Override
16997         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
16998             synchronized (mPackages) {
16999                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
17000             }
17001         }
17002
17003         @Override
17004         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
17005             synchronized (mPackages) {
17006                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
17007                         packageName, userId);
17008             }
17009         }
17010
17011         @Override
17012         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
17013             synchronized (mPackages) {
17014                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
17015                         packageName, userId);
17016             }
17017         }
17018         @Override
17019         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
17020             synchronized (mPackages) {
17021                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
17022                         packageName, userId);
17023             }
17024         }
17025     }
17026
17027     @Override
17028     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
17029         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
17030         synchronized (mPackages) {
17031             final long identity = Binder.clearCallingIdentity();
17032             try {
17033                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
17034                         packageNames, userId);
17035             } finally {
17036                 Binder.restoreCallingIdentity(identity);
17037             }
17038         }
17039     }
17040
17041     private static void enforceSystemOrPhoneCaller(String tag) {
17042         int callingUid = Binder.getCallingUid();
17043         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
17044             throw new SecurityException(
17045                     "Cannot call " + tag + " from UID " + callingUid);
17046         }
17047     }
17048 }