OSDN Git Service

[automerger] Limit IsSeparateProfileChallengeAllowed to system callers am: 9061fcc46b...
[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.DELETE_KEEP_DATA;
28 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
29 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
30 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
31 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
32 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
33 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
34 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
35 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
36 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
37 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
38 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
39 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
44 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
45 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
46 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
47 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
48 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
49 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
50 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
51 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
52 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
53 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
54 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
55 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
56 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
57 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
58 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
59 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
60 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
61 import static android.content.pm.PackageManager.MATCH_ALL;
62 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
63 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
64 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
65 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
66 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
67 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
68 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
69 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
70 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
71 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
72 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
73 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
74 import static android.content.pm.PackageManager.PERMISSION_DENIED;
75 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
76 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
77 import static android.content.pm.PackageParser.isApkFile;
78 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
79 import static android.system.OsConstants.O_CREAT;
80 import static android.system.OsConstants.O_RDWR;
81
82 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
83 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
84 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
85 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
86 import static com.android.internal.util.ArrayUtils.appendInt;
87 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
88 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
89 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
90 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
91 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
92 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
93 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
94 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
95 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
96 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
97 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
98 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
99
100 import android.Manifest;
101 import android.annotation.NonNull;
102 import android.annotation.Nullable;
103 import android.app.ActivityManager;
104 import android.app.ActivityManagerNative;
105 import android.app.IActivityManager;
106 import android.app.ResourcesManager;
107 import android.app.admin.IDevicePolicyManager;
108 import android.app.admin.SecurityLog;
109 import android.app.backup.IBackupManager;
110 import android.content.BroadcastReceiver;
111 import android.content.ComponentName;
112 import android.content.ContentResolver;
113 import android.content.Context;
114 import android.content.IIntentReceiver;
115 import android.content.Intent;
116 import android.content.IntentFilter;
117 import android.content.IntentSender;
118 import android.content.IntentSender.SendIntentException;
119 import android.content.ServiceConnection;
120 import android.content.pm.ActivityInfo;
121 import android.content.pm.ApplicationInfo;
122 import android.content.pm.AppsQueryHelper;
123 import android.content.pm.ComponentInfo;
124 import android.content.pm.EphemeralApplicationInfo;
125 import android.content.pm.EphemeralResolveInfo;
126 import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
127 import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
128 import android.content.pm.FeatureInfo;
129 import android.content.pm.IOnPermissionsChangeListener;
130 import android.content.pm.IPackageDataObserver;
131 import android.content.pm.IPackageDeleteObserver;
132 import android.content.pm.IPackageDeleteObserver2;
133 import android.content.pm.IPackageInstallObserver2;
134 import android.content.pm.IPackageInstaller;
135 import android.content.pm.IPackageManager;
136 import android.content.pm.IPackageMoveObserver;
137 import android.content.pm.IPackageStatsObserver;
138 import android.content.pm.InstrumentationInfo;
139 import android.content.pm.IntentFilterVerificationInfo;
140 import android.content.pm.KeySet;
141 import android.content.pm.PackageCleanItem;
142 import android.content.pm.PackageInfo;
143 import android.content.pm.PackageInfoLite;
144 import android.content.pm.PackageInstaller;
145 import android.content.pm.PackageManager;
146 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
147 import android.content.pm.PackageManagerInternal;
148 import android.content.pm.PackageParser;
149 import android.content.pm.PackageParser.ActivityIntentInfo;
150 import android.content.pm.PackageParser.PackageLite;
151 import android.content.pm.PackageParser.PackageParserException;
152 import android.content.pm.PackageStats;
153 import android.content.pm.PackageUserState;
154 import android.content.pm.ParceledListSlice;
155 import android.content.pm.PermissionGroupInfo;
156 import android.content.pm.PermissionInfo;
157 import android.content.pm.ProviderInfo;
158 import android.content.pm.ResolveInfo;
159 import android.content.pm.ServiceInfo;
160 import android.content.pm.Signature;
161 import android.content.pm.UserInfo;
162 import android.content.pm.VerifierDeviceIdentity;
163 import android.content.pm.VerifierInfo;
164 import android.content.res.Resources;
165 import android.graphics.Bitmap;
166 import android.hardware.display.DisplayManager;
167 import android.net.Uri;
168 import android.os.AsyncTask;
169 import android.os.Binder;
170 import android.os.Build;
171 import android.os.Bundle;
172 import android.os.Debug;
173 import android.os.Environment;
174 import android.os.Environment.UserEnvironment;
175 import android.os.FileUtils;
176 import android.os.Handler;
177 import android.os.IBinder;
178 import android.os.Looper;
179 import android.os.Message;
180 import android.os.Parcel;
181 import android.os.ParcelFileDescriptor;
182 import android.os.PatternMatcher;
183 import android.os.Process;
184 import android.os.RemoteCallbackList;
185 import android.os.RemoteException;
186 import android.os.ResultReceiver;
187 import android.os.SELinux;
188 import android.os.ServiceManager;
189 import android.os.SystemClock;
190 import android.os.SystemProperties;
191 import android.os.Trace;
192 import android.os.UserHandle;
193 import android.os.UserManager;
194 import android.os.UserManagerInternal;
195 import android.os.storage.IMountService;
196 import android.os.storage.MountServiceInternal;
197 import android.os.storage.StorageEventListener;
198 import android.os.storage.StorageManager;
199 import android.os.storage.VolumeInfo;
200 import android.os.storage.VolumeRecord;
201 import android.provider.Settings.Global;
202 import android.provider.Settings.Secure;
203 import android.security.KeyStore;
204 import android.security.SystemKeyStore;
205 import android.system.ErrnoException;
206 import android.system.Os;
207 import android.text.TextUtils;
208 import android.text.format.DateUtils;
209 import android.util.ArrayMap;
210 import android.util.ArraySet;
211 import android.util.DisplayMetrics;
212 import android.util.EventLog;
213 import android.util.ExceptionUtils;
214 import android.util.Log;
215 import android.util.LogPrinter;
216 import android.util.MathUtils;
217 import android.util.Pair;
218 import android.util.PrintStreamPrinter;
219 import android.util.Slog;
220 import android.util.SparseArray;
221 import android.util.SparseBooleanArray;
222 import android.util.SparseIntArray;
223 import android.util.Xml;
224 import android.util.jar.StrictJarFile;
225 import android.view.Display;
226
227 import com.android.internal.R;
228 import com.android.internal.annotations.GuardedBy;
229 import com.android.internal.app.IMediaContainerService;
230 import com.android.internal.app.ResolverActivity;
231 import com.android.internal.content.NativeLibraryHelper;
232 import com.android.internal.content.PackageHelper;
233 import com.android.internal.logging.MetricsLogger;
234 import com.android.internal.os.IParcelFileDescriptorFactory;
235 import com.android.internal.os.InstallerConnection.InstallerException;
236 import com.android.internal.os.SomeArgs;
237 import com.android.internal.os.Zygote;
238 import com.android.internal.telephony.CarrierAppUtils;
239 import com.android.internal.util.ArrayUtils;
240 import com.android.internal.util.FastPrintWriter;
241 import com.android.internal.util.FastXmlSerializer;
242 import com.android.internal.util.IndentingPrintWriter;
243 import com.android.internal.util.Preconditions;
244 import com.android.internal.util.XmlUtils;
245 import com.android.server.AttributeCache;
246 import com.android.server.EventLogTags;
247 import com.android.server.FgThread;
248 import com.android.server.IntentResolver;
249 import com.android.server.LocalServices;
250 import com.android.server.ServiceThread;
251 import com.android.server.SystemConfig;
252 import com.android.server.Watchdog;
253 import com.android.server.net.NetworkPolicyManagerInternal;
254 import com.android.server.pm.PermissionsState.PermissionState;
255 import com.android.server.pm.Settings.DatabaseVersion;
256 import com.android.server.pm.Settings.VersionInfo;
257 import com.android.server.storage.DeviceStorageMonitorInternal;
258
259 import dalvik.system.CloseGuard;
260 import dalvik.system.DexFile;
261 import dalvik.system.VMRuntime;
262
263 import libcore.io.IoUtils;
264 import libcore.util.EmptyArray;
265
266 import org.xmlpull.v1.XmlPullParser;
267 import org.xmlpull.v1.XmlPullParserException;
268 import org.xmlpull.v1.XmlSerializer;
269
270 import java.io.BufferedOutputStream;
271 import java.io.BufferedReader;
272 import java.io.ByteArrayInputStream;
273 import java.io.ByteArrayOutputStream;
274 import java.io.File;
275 import java.io.FileDescriptor;
276 import java.io.FileInputStream;
277 import java.io.FileNotFoundException;
278 import java.io.FileOutputStream;
279 import java.io.FileReader;
280 import java.io.FilenameFilter;
281 import java.io.IOException;
282 import java.io.PrintWriter;
283 import java.nio.charset.StandardCharsets;
284 import java.security.DigestInputStream;
285 import java.security.MessageDigest;
286 import java.security.NoSuchAlgorithmException;
287 import java.security.PublicKey;
288 import java.security.cert.Certificate;
289 import java.security.cert.CertificateEncodingException;
290 import java.security.cert.CertificateException;
291 import java.text.SimpleDateFormat;
292 import java.util.ArrayList;
293 import java.util.Arrays;
294 import java.util.Collection;
295 import java.util.Collections;
296 import java.util.Comparator;
297 import java.util.Date;
298 import java.util.HashSet;
299 import java.util.Iterator;
300 import java.util.List;
301 import java.util.Map;
302 import java.util.Objects;
303 import java.util.Set;
304 import java.util.concurrent.CountDownLatch;
305 import java.util.concurrent.TimeUnit;
306 import java.util.concurrent.atomic.AtomicBoolean;
307 import java.util.concurrent.atomic.AtomicInteger;
308
309 /**
310  * Keep track of all those APKs everywhere.
311  * <p>
312  * Internally there are two important locks:
313  * <ul>
314  * <li>{@link #mPackages} is used to guard all in-memory parsed package details
315  * and other related state. It is a fine-grained lock that should only be held
316  * momentarily, as it's one of the most contended locks in the system.
317  * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
318  * operations typically involve heavy lifting of application data on disk. Since
319  * {@code installd} is single-threaded, and it's operations can often be slow,
320  * this lock should never be acquired while already holding {@link #mPackages}.
321  * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
322  * holding {@link #mInstallLock}.
323  * </ul>
324  * Many internal methods rely on the caller to hold the appropriate locks, and
325  * this contract is expressed through method name suffixes:
326  * <ul>
327  * <li>fooLI(): the caller must hold {@link #mInstallLock}
328  * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
329  * being modified must be frozen
330  * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
331  * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
332  * </ul>
333  * <p>
334  * Because this class is very central to the platform's security; please run all
335  * CTS and unit tests whenever making modifications:
336  *
337  * <pre>
338  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
339  * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
340  * </pre>
341  */
342 public class PackageManagerService extends IPackageManager.Stub {
343     static final String TAG = "PackageManager";
344     static final boolean DEBUG_SETTINGS = false;
345     static final boolean DEBUG_PREFERRED = false;
346     static final boolean DEBUG_UPGRADE = false;
347     static final boolean DEBUG_DOMAIN_VERIFICATION = false;
348     private static final boolean DEBUG_BACKUP = false;
349     private static final boolean DEBUG_INSTALL = false;
350     private static final boolean DEBUG_REMOVE = false;
351     private static final boolean DEBUG_BROADCASTS = false;
352     private static final boolean DEBUG_SHOW_INFO = false;
353     private static final boolean DEBUG_PACKAGE_INFO = false;
354     private static final boolean DEBUG_INTENT_MATCHING = false;
355     private static final boolean DEBUG_PACKAGE_SCANNING = false;
356     private static final boolean DEBUG_VERIFY = false;
357     private static final boolean DEBUG_FILTERS = false;
358
359     // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
360     // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
361     // user, but by default initialize to this.
362     static final boolean DEBUG_DEXOPT = false;
363
364     private static final boolean DEBUG_ABI_SELECTION = false;
365     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
366     private static final boolean DEBUG_TRIAGED_MISSING = false;
367     private static final boolean DEBUG_APP_DATA = false;
368
369     static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
370
371     private static final boolean DISABLE_EPHEMERAL_APPS = false;
372     private static final boolean HIDE_EPHEMERAL_APIS = true;
373
374     private static final int RADIO_UID = Process.PHONE_UID;
375     private static final int LOG_UID = Process.LOG_UID;
376     private static final int NFC_UID = Process.NFC_UID;
377     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
378     private static final int SHELL_UID = Process.SHELL_UID;
379
380     // Cap the size of permission trees that 3rd party apps can define
381     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
382
383     // Suffix used during package installation when copying/moving
384     // package apks to install directory.
385     private static final String INSTALL_PACKAGE_SUFFIX = "-";
386
387     static final int SCAN_NO_DEX = 1<<1;
388     static final int SCAN_FORCE_DEX = 1<<2;
389     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
390     static final int SCAN_NEW_INSTALL = 1<<4;
391     static final int SCAN_NO_PATHS = 1<<5;
392     static final int SCAN_UPDATE_TIME = 1<<6;
393     static final int SCAN_DEFER_DEX = 1<<7;
394     static final int SCAN_BOOTING = 1<<8;
395     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
396     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
397     static final int SCAN_REPLACING = 1<<11;
398     static final int SCAN_REQUIRE_KNOWN = 1<<12;
399     static final int SCAN_MOVE = 1<<13;
400     static final int SCAN_INITIAL = 1<<14;
401     static final int SCAN_CHECK_ONLY = 1<<15;
402     static final int SCAN_DONT_KILL_APP = 1<<17;
403     static final int SCAN_IGNORE_FROZEN = 1<<18;
404
405     static final int REMOVE_CHATTY = 1<<16;
406
407     private static final int[] EMPTY_INT_ARRAY = new int[0];
408
409     /**
410      * Timeout (in milliseconds) after which the watchdog should declare that
411      * our handler thread is wedged.  The usual default for such things is one
412      * minute but we sometimes do very lengthy I/O operations on this thread,
413      * such as installing multi-gigabyte applications, so ours needs to be longer.
414      */
415     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
416
417     /**
418      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
419      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
420      * settings entry if available, otherwise we use the hardcoded default.  If it's been
421      * more than this long since the last fstrim, we force one during the boot sequence.
422      *
423      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
424      * one gets run at the next available charging+idle time.  This final mandatory
425      * no-fstrim check kicks in only of the other scheduling criteria is never met.
426      */
427     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
428
429     /**
430      * Whether verification is enabled by default.
431      */
432     private static final boolean DEFAULT_VERIFY_ENABLE = true;
433
434     /**
435      * The default maximum time to wait for the verification agent to return in
436      * milliseconds.
437      */
438     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
439
440     /**
441      * The default response for package verification timeout.
442      *
443      * This can be either PackageManager.VERIFICATION_ALLOW or
444      * PackageManager.VERIFICATION_REJECT.
445      */
446     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
447
448     static final String PLATFORM_PACKAGE_NAME = "android";
449
450     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
451
452     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
453             DEFAULT_CONTAINER_PACKAGE,
454             "com.android.defcontainer.DefaultContainerService");
455
456     private static final String KILL_APP_REASON_GIDS_CHANGED =
457             "permission grant or revoke changed gids";
458
459     private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
460             "permissions revoked";
461
462     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
463
464     private static final String PACKAGE_SCHEME = "package";
465
466     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
467
468     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000;
469     private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5;
470
471     /** Permission grant: not grant the permission. */
472     private static final int GRANT_DENIED = 1;
473
474     /** Permission grant: grant the permission as an install permission. */
475     private static final int GRANT_INSTALL = 2;
476
477     /** Permission grant: grant the permission as a runtime one. */
478     private static final int GRANT_RUNTIME = 3;
479
480     /** Permission grant: grant as runtime a permission that was granted as an install time one. */
481     private static final int GRANT_UPGRADE = 4;
482
483     /** Canonical intent used to identify what counts as a "web browser" app */
484     private static final Intent sBrowserIntent;
485     static {
486         sBrowserIntent = new Intent();
487         sBrowserIntent.setAction(Intent.ACTION_VIEW);
488         sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
489         sBrowserIntent.setData(Uri.parse("http:"));
490     }
491
492     /**
493      * The set of all protected actions [i.e. those actions for which a high priority
494      * intent filter is disallowed].
495      */
496     private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
497     static {
498         PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
499         PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
500         PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
501         PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
502     }
503
504     // Compilation reasons.
505     public static final int REASON_FIRST_BOOT = 0;
506     public static final int REASON_BOOT = 1;
507     public static final int REASON_INSTALL = 2;
508     public static final int REASON_BACKGROUND_DEXOPT = 3;
509     public static final int REASON_AB_OTA = 4;
510     public static final int REASON_NON_SYSTEM_LIBRARY = 5;
511     public static final int REASON_SHARED_APK = 6;
512     public static final int REASON_FORCED_DEXOPT = 7;
513     public static final int REASON_CORE_APP = 8;
514
515     public static final int REASON_LAST = REASON_CORE_APP;
516
517     /** Special library name that skips shared libraries check during compilation. */
518     private static final String SKIP_SHARED_LIBRARY_CHECK = "&";
519
520     final ServiceThread mHandlerThread;
521
522     final PackageHandler mHandler;
523
524     private final ProcessLoggingHandler mProcessLoggingHandler;
525
526     /**
527      * Messages for {@link #mHandler} that need to wait for system ready before
528      * being dispatched.
529      */
530     private ArrayList<Message> mPostSystemReadyMessages;
531
532     final int mSdkVersion = Build.VERSION.SDK_INT;
533
534     final Context mContext;
535     final boolean mFactoryTest;
536     final boolean mOnlyCore;
537     final DisplayMetrics mMetrics;
538     final int mDefParseFlags;
539     final String[] mSeparateProcesses;
540     final boolean mIsUpgrade;
541     final boolean mIsPreNUpgrade;
542     final boolean mIsPreNMR1Upgrade;
543
544     @GuardedBy("mPackages")
545     private boolean mDexOptDialogShown;
546
547     /** The location for ASEC container files on internal storage. */
548     final String mAsecInternalPath;
549
550     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
551     // LOCK HELD.  Can be called with mInstallLock held.
552     @GuardedBy("mInstallLock")
553     final Installer mInstaller;
554
555     /** Directory where installed third-party apps stored */
556     final File mAppInstallDir;
557     final File mEphemeralInstallDir;
558
559     /**
560      * Directory to which applications installed internally have their
561      * 32 bit native libraries copied.
562      */
563     private File mAppLib32InstallDir;
564
565     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
566     // apps.
567     final File mDrmAppPrivateInstallDir;
568
569     // ----------------------------------------------------------------
570
571     // Lock for state used when installing and doing other long running
572     // operations.  Methods that must be called with this lock held have
573     // the suffix "LI".
574     final Object mInstallLock = new Object();
575
576     // ----------------------------------------------------------------
577
578     // Keys are String (package name), values are Package.  This also serves
579     // as the lock for the global state.  Methods that must be called with
580     // this lock held have the prefix "LP".
581     @GuardedBy("mPackages")
582     final ArrayMap<String, PackageParser.Package> mPackages =
583             new ArrayMap<String, PackageParser.Package>();
584
585     final ArrayMap<String, Set<String>> mKnownCodebase =
586             new ArrayMap<String, Set<String>>();
587
588     // Tracks available target package names -> overlay package paths.
589     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
590         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
591
592     /**
593      * Tracks new system packages [received in an OTA] that we expect to
594      * find updated user-installed versions. Keys are package name, values
595      * are package location.
596      */
597     final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
598     /**
599      * Tracks high priority intent filters for protected actions. During boot, certain
600      * filter actions are protected and should never be allowed to have a high priority
601      * intent filter for them. However, there is one, and only one exception -- the
602      * setup wizard. It must be able to define a high priority intent filter for these
603      * actions to ensure there are no escapes from the wizard. We need to delay processing
604      * of these during boot as we need to look at all of the system packages in order
605      * to know which component is the setup wizard.
606      */
607     private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
608     /**
609      * Whether or not processing protected filters should be deferred.
610      */
611     private boolean mDeferProtectedFilters = true;
612
613     /**
614      * Tracks existing system packages prior to receiving an OTA. Keys are package name.
615      */
616     final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
617     /**
618      * Whether or not system app permissions should be promoted from install to runtime.
619      */
620     boolean mPromoteSystemApps;
621
622     @GuardedBy("mPackages")
623     final Settings mSettings;
624
625     /**
626      * Set of package names that are currently "frozen", which means active
627      * surgery is being done on the code/data for that package. The platform
628      * will refuse to launch frozen packages to avoid race conditions.
629      *
630      * @see PackageFreezer
631      */
632     @GuardedBy("mPackages")
633     final ArraySet<String> mFrozenPackages = new ArraySet<>();
634
635     final ProtectedPackages mProtectedPackages;
636
637     boolean mFirstBoot;
638
639     // System configuration read by SystemConfig.
640     final int[] mGlobalGids;
641     final SparseArray<ArraySet<String>> mSystemPermissions;
642     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
643
644     // If mac_permissions.xml was found for seinfo labeling.
645     boolean mFoundPolicyFile;
646
647     private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
648
649     public static final class SharedLibraryEntry {
650         public final String path;
651         public final String apk;
652
653         SharedLibraryEntry(String _path, String _apk) {
654             path = _path;
655             apk = _apk;
656         }
657     }
658
659     // Currently known shared libraries.
660     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
661             new ArrayMap<String, SharedLibraryEntry>();
662
663     // All available activities, for your resolving pleasure.
664     final ActivityIntentResolver mActivities =
665             new ActivityIntentResolver();
666
667     // All available receivers, for your resolving pleasure.
668     final ActivityIntentResolver mReceivers =
669             new ActivityIntentResolver();
670
671     // All available services, for your resolving pleasure.
672     final ServiceIntentResolver mServices = new ServiceIntentResolver();
673
674     // All available providers, for your resolving pleasure.
675     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
676
677     // Mapping from provider base names (first directory in content URI codePath)
678     // to the provider information.
679     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
680             new ArrayMap<String, PackageParser.Provider>();
681
682     // Mapping from instrumentation class names to info about them.
683     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
684             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
685
686     // Mapping from permission names to info about them.
687     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
688             new ArrayMap<String, PackageParser.PermissionGroup>();
689
690     // Packages whose data we have transfered into another package, thus
691     // should no longer exist.
692     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
693
694     // Broadcast actions that are only available to the system.
695     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
696
697     /** List of packages waiting for verification. */
698     final SparseArray<PackageVerificationState> mPendingVerification
699             = new SparseArray<PackageVerificationState>();
700
701     /** Set of packages associated with each app op permission. */
702     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
703
704     final PackageInstallerService mInstallerService;
705
706     private final PackageDexOptimizer mPackageDexOptimizer;
707
708     private AtomicInteger mNextMoveId = new AtomicInteger();
709     private final MoveCallbacks mMoveCallbacks;
710
711     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
712
713     // Cache of users who need badging.
714     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
715
716     /** Token for keys in mPendingVerification. */
717     private int mPendingVerificationToken = 0;
718
719     volatile boolean mSystemReady;
720     volatile boolean mSafeMode;
721     volatile boolean mHasSystemUidErrors;
722
723     ApplicationInfo mAndroidApplication;
724     final ActivityInfo mResolveActivity = new ActivityInfo();
725     final ResolveInfo mResolveInfo = new ResolveInfo();
726     ComponentName mResolveComponentName;
727     PackageParser.Package mPlatformPackage;
728     ComponentName mCustomResolverComponentName;
729
730     boolean mResolverReplaced = false;
731
732     private final @Nullable ComponentName mIntentFilterVerifierComponent;
733     private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
734
735     private int mIntentFilterVerificationToken = 0;
736
737     /** Component that knows whether or not an ephemeral application exists */
738     final ComponentName mEphemeralResolverComponent;
739     /** The service connection to the ephemeral resolver */
740     final EphemeralResolverConnection mEphemeralResolverConnection;
741
742     /** Component used to install ephemeral applications */
743     final ComponentName mEphemeralInstallerComponent;
744     final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
745     final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
746
747     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
748             = new SparseArray<IntentFilterVerificationState>();
749
750     final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
751
752     // List of packages names to keep cached, even if they are uninstalled for all users
753     private List<String> mKeepUninstalledPackages;
754
755     private UserManagerInternal mUserManagerInternal;
756
757     private static class IFVerificationParams {
758         PackageParser.Package pkg;
759         boolean replacing;
760         int userId;
761         int verifierUid;
762
763         public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
764                 int _userId, int _verifierUid) {
765             pkg = _pkg;
766             replacing = _replacing;
767             userId = _userId;
768             replacing = _replacing;
769             verifierUid = _verifierUid;
770         }
771     }
772
773     private interface IntentFilterVerifier<T extends IntentFilter> {
774         boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
775                                                T filter, String packageName);
776         void startVerifications(int userId);
777         void receiveVerificationResponse(int verificationId);
778     }
779
780     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
781         private Context mContext;
782         private ComponentName mIntentFilterVerifierComponent;
783         private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
784
785         public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
786             mContext = context;
787             mIntentFilterVerifierComponent = verifierComponent;
788         }
789
790         private String getDefaultScheme() {
791             return IntentFilter.SCHEME_HTTPS;
792         }
793
794         @Override
795         public void startVerifications(int userId) {
796             // Launch verifications requests
797             int count = mCurrentIntentFilterVerifications.size();
798             for (int n=0; n<count; n++) {
799                 int verificationId = mCurrentIntentFilterVerifications.get(n);
800                 final IntentFilterVerificationState ivs =
801                         mIntentFilterVerificationStates.get(verificationId);
802
803                 String packageName = ivs.getPackageName();
804
805                 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
806                 final int filterCount = filters.size();
807                 ArraySet<String> domainsSet = new ArraySet<>();
808                 for (int m=0; m<filterCount; m++) {
809                     PackageParser.ActivityIntentInfo filter = filters.get(m);
810                     domainsSet.addAll(filter.getHostsList());
811                 }
812                 ArrayList<String> domainsList = new ArrayList<>(domainsSet);
813                 synchronized (mPackages) {
814                     if (mSettings.createIntentFilterVerificationIfNeededLPw(
815                             packageName, domainsList) != null) {
816                         scheduleWriteSettingsLocked();
817                     }
818                 }
819                 sendVerificationRequest(userId, verificationId, ivs);
820             }
821             mCurrentIntentFilterVerifications.clear();
822         }
823
824         private void sendVerificationRequest(int userId, int verificationId,
825                 IntentFilterVerificationState ivs) {
826
827             Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
828             verificationIntent.putExtra(
829                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
830                     verificationId);
831             verificationIntent.putExtra(
832                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
833                     getDefaultScheme());
834             verificationIntent.putExtra(
835                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
836                     ivs.getHostsString());
837             verificationIntent.putExtra(
838                     PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
839                     ivs.getPackageName());
840             verificationIntent.setComponent(mIntentFilterVerifierComponent);
841             verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
842
843             UserHandle user = new UserHandle(userId);
844             mContext.sendBroadcastAsUser(verificationIntent, user);
845             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
846                     "Sending IntentFilter verification broadcast");
847         }
848
849         public void receiveVerificationResponse(int verificationId) {
850             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
851
852             final boolean verified = ivs.isVerified();
853
854             ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
855             final int count = filters.size();
856             if (DEBUG_DOMAIN_VERIFICATION) {
857                 Slog.i(TAG, "Received verification response " + verificationId
858                         + " for " + count + " filters, verified=" + verified);
859             }
860             for (int n=0; n<count; n++) {
861                 PackageParser.ActivityIntentInfo filter = filters.get(n);
862                 filter.setVerified(verified);
863
864                 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
865                         + " verified with result:" + verified + " and hosts:"
866                         + ivs.getHostsString());
867             }
868
869             mIntentFilterVerificationStates.remove(verificationId);
870
871             final String packageName = ivs.getPackageName();
872             IntentFilterVerificationInfo ivi = null;
873
874             synchronized (mPackages) {
875                 ivi = mSettings.getIntentFilterVerificationLPr(packageName);
876             }
877             if (ivi == null) {
878                 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
879                         + verificationId + " packageName:" + packageName);
880                 return;
881             }
882             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
883                     "Updating IntentFilterVerificationInfo for package " + packageName
884                             +" verificationId:" + verificationId);
885
886             synchronized (mPackages) {
887                 if (verified) {
888                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
889                 } else {
890                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
891                 }
892                 scheduleWriteSettingsLocked();
893
894                 final int userId = ivs.getUserId();
895                 if (userId != UserHandle.USER_ALL) {
896                     final int userStatus =
897                             mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
898
899                     int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
900                     boolean needUpdate = false;
901
902                     // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
903                     // already been set by the User thru the Disambiguation dialog
904                     switch (userStatus) {
905                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
906                             if (verified) {
907                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
908                             } else {
909                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
910                             }
911                             needUpdate = true;
912                             break;
913
914                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
915                             if (verified) {
916                                 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
917                                 needUpdate = true;
918                             }
919                             break;
920
921                         default:
922                             // Nothing to do
923                     }
924
925                     if (needUpdate) {
926                         mSettings.updateIntentFilterVerificationStatusLPw(
927                                 packageName, updatedStatus, userId);
928                         scheduleWritePackageRestrictionsLocked(userId);
929                     }
930                 }
931             }
932         }
933
934         @Override
935         public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
936                     ActivityIntentInfo filter, String packageName) {
937             if (!hasValidDomains(filter)) {
938                 return false;
939             }
940             IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
941             if (ivs == null) {
942                 ivs = createDomainVerificationState(verifierUid, userId, verificationId,
943                         packageName);
944             }
945             if (DEBUG_DOMAIN_VERIFICATION) {
946                 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
947             }
948             ivs.addFilter(filter);
949             return true;
950         }
951
952         private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
953                 int userId, int verificationId, String packageName) {
954             IntentFilterVerificationState ivs = new IntentFilterVerificationState(
955                     verifierUid, userId, packageName);
956             ivs.setPendingState();
957             synchronized (mPackages) {
958                 mIntentFilterVerificationStates.append(verificationId, ivs);
959                 mCurrentIntentFilterVerifications.add(verificationId);
960             }
961             return ivs;
962         }
963     }
964
965     private static boolean hasValidDomains(ActivityIntentInfo filter) {
966         return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
967                 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
968                         filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
969     }
970
971     // Set of pending broadcasts for aggregating enable/disable of components.
972     static class PendingPackageBroadcasts {
973         // for each user id, a map of <package name -> components within that package>
974         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
975
976         public PendingPackageBroadcasts() {
977             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
978         }
979
980         public ArrayList<String> get(int userId, String packageName) {
981             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
982             return packages.get(packageName);
983         }
984
985         public void put(int userId, String packageName, ArrayList<String> components) {
986             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
987             packages.put(packageName, components);
988         }
989
990         public void remove(int userId, String packageName) {
991             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
992             if (packages != null) {
993                 packages.remove(packageName);
994             }
995         }
996
997         public void remove(int userId) {
998             mUidMap.remove(userId);
999         }
1000
1001         public int userIdCount() {
1002             return mUidMap.size();
1003         }
1004
1005         public int userIdAt(int n) {
1006             return mUidMap.keyAt(n);
1007         }
1008
1009         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1010             return mUidMap.get(userId);
1011         }
1012
1013         public int size() {
1014             // total number of pending broadcast entries across all userIds
1015             int num = 0;
1016             for (int i = 0; i< mUidMap.size(); i++) {
1017                 num += mUidMap.valueAt(i).size();
1018             }
1019             return num;
1020         }
1021
1022         public void clear() {
1023             mUidMap.clear();
1024         }
1025
1026         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1027             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1028             if (map == null) {
1029                 map = new ArrayMap<String, ArrayList<String>>();
1030                 mUidMap.put(userId, map);
1031             }
1032             return map;
1033         }
1034     }
1035     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1036
1037     // Service Connection to remote media container service to copy
1038     // package uri's from external media onto secure containers
1039     // or internal storage.
1040     private IMediaContainerService mContainerService = null;
1041
1042     static final int SEND_PENDING_BROADCAST = 1;
1043     static final int MCS_BOUND = 3;
1044     static final int END_COPY = 4;
1045     static final int INIT_COPY = 5;
1046     static final int MCS_UNBIND = 6;
1047     static final int START_CLEANING_PACKAGE = 7;
1048     static final int FIND_INSTALL_LOC = 8;
1049     static final int POST_INSTALL = 9;
1050     static final int MCS_RECONNECT = 10;
1051     static final int MCS_GIVE_UP = 11;
1052     static final int UPDATED_MEDIA_STATUS = 12;
1053     static final int WRITE_SETTINGS = 13;
1054     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1055     static final int PACKAGE_VERIFIED = 15;
1056     static final int CHECK_PENDING_VERIFICATION = 16;
1057     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1058     static final int INTENT_FILTER_VERIFIED = 18;
1059     static final int WRITE_PACKAGE_LIST = 19;
1060
1061     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1062
1063     // Delay time in millisecs
1064     static final int BROADCAST_DELAY = 10 * 1000;
1065
1066     static UserManagerService sUserManager;
1067
1068     // Stores a list of users whose package restrictions file needs to be updated
1069     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1070
1071     final private DefaultContainerConnection mDefContainerConn =
1072             new DefaultContainerConnection();
1073     class DefaultContainerConnection implements ServiceConnection {
1074         public void onServiceConnected(ComponentName name, IBinder service) {
1075             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1076             IMediaContainerService imcs =
1077                 IMediaContainerService.Stub.asInterface(service);
1078             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1079         }
1080
1081         public void onServiceDisconnected(ComponentName name) {
1082             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1083         }
1084     }
1085
1086     // Recordkeeping of restore-after-install operations that are currently in flight
1087     // between the Package Manager and the Backup Manager
1088     static class PostInstallData {
1089         public InstallArgs args;
1090         public PackageInstalledInfo res;
1091
1092         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1093             args = _a;
1094             res = _r;
1095         }
1096     }
1097
1098     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1099     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1100
1101     // XML tags for backup/restore of various bits of state
1102     private static final String TAG_PREFERRED_BACKUP = "pa";
1103     private static final String TAG_DEFAULT_APPS = "da";
1104     private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1105
1106     private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1107     private static final String TAG_ALL_GRANTS = "rt-grants";
1108     private static final String TAG_GRANT = "grant";
1109     private static final String ATTR_PACKAGE_NAME = "pkg";
1110
1111     private static final String TAG_PERMISSION = "perm";
1112     private static final String ATTR_PERMISSION_NAME = "name";
1113     private static final String ATTR_IS_GRANTED = "g";
1114     private static final String ATTR_USER_SET = "set";
1115     private static final String ATTR_USER_FIXED = "fixed";
1116     private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1117
1118     // System/policy permission grants are not backed up
1119     private static final int SYSTEM_RUNTIME_GRANT_MASK =
1120             FLAG_PERMISSION_POLICY_FIXED
1121             | FLAG_PERMISSION_SYSTEM_FIXED
1122             | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1123
1124     // And we back up these user-adjusted states
1125     private static final int USER_RUNTIME_GRANT_MASK =
1126             FLAG_PERMISSION_USER_SET
1127             | FLAG_PERMISSION_USER_FIXED
1128             | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1129
1130     final @Nullable String mRequiredVerifierPackage;
1131     final @NonNull String mRequiredInstallerPackage;
1132     final @NonNull String mRequiredUninstallerPackage;
1133     final @Nullable String mSetupWizardPackage;
1134     final @Nullable String mStorageManagerPackage;
1135     final @NonNull String mServicesSystemSharedLibraryPackageName;
1136     final @NonNull String mSharedSystemSharedLibraryPackageName;
1137
1138     private final PackageUsage mPackageUsage = new PackageUsage();
1139     private final CompilerStats mCompilerStats = new CompilerStats();
1140
1141     class PackageHandler extends Handler {
1142         private boolean mBound = false;
1143         final ArrayList<HandlerParams> mPendingInstalls =
1144             new ArrayList<HandlerParams>();
1145
1146         private boolean connectToService() {
1147             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1148                     " DefaultContainerService");
1149             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1150             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1151             if (mContext.bindServiceAsUser(service, mDefContainerConn,
1152                     Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1153                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1154                 mBound = true;
1155                 return true;
1156             }
1157             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1158             return false;
1159         }
1160
1161         private void disconnectService() {
1162             mContainerService = null;
1163             mBound = false;
1164             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1165             mContext.unbindService(mDefContainerConn);
1166             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1167         }
1168
1169         PackageHandler(Looper looper) {
1170             super(looper);
1171         }
1172
1173         public void handleMessage(Message msg) {
1174             try {
1175                 doHandleMessage(msg);
1176             } finally {
1177                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1178             }
1179         }
1180
1181         void doHandleMessage(Message msg) {
1182             switch (msg.what) {
1183                 case INIT_COPY: {
1184                     HandlerParams params = (HandlerParams) msg.obj;
1185                     int idx = mPendingInstalls.size();
1186                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1187                     // If a bind was already initiated we dont really
1188                     // need to do anything. The pending install
1189                     // will be processed later on.
1190                     if (!mBound) {
1191                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1192                                 System.identityHashCode(mHandler));
1193                         // If this is the only one pending we might
1194                         // have to bind to the service again.
1195                         if (!connectToService()) {
1196                             Slog.e(TAG, "Failed to bind to media container service");
1197                             params.serviceError();
1198                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1199                                     System.identityHashCode(mHandler));
1200                             if (params.traceMethod != null) {
1201                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1202                                         params.traceCookie);
1203                             }
1204                             return;
1205                         } else {
1206                             // Once we bind to the service, the first
1207                             // pending request will be processed.
1208                             mPendingInstalls.add(idx, params);
1209                         }
1210                     } else {
1211                         mPendingInstalls.add(idx, params);
1212                         // Already bound to the service. Just make
1213                         // sure we trigger off processing the first request.
1214                         if (idx == 0) {
1215                             mHandler.sendEmptyMessage(MCS_BOUND);
1216                         }
1217                     }
1218                     break;
1219                 }
1220                 case MCS_BOUND: {
1221                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1222                     if (msg.obj != null) {
1223                         mContainerService = (IMediaContainerService) msg.obj;
1224                         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1225                                 System.identityHashCode(mHandler));
1226                     }
1227                     if (mContainerService == null) {
1228                         if (!mBound) {
1229                             // Something seriously wrong since we are not bound and we are not
1230                             // waiting for connection. Bail out.
1231                             Slog.e(TAG, "Cannot bind to media container service");
1232                             for (HandlerParams params : mPendingInstalls) {
1233                                 // Indicate service bind error
1234                                 params.serviceError();
1235                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1236                                         System.identityHashCode(params));
1237                                 if (params.traceMethod != null) {
1238                                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1239                                             params.traceMethod, params.traceCookie);
1240                                 }
1241                                 return;
1242                             }
1243                             mPendingInstalls.clear();
1244                         } else {
1245                             Slog.w(TAG, "Waiting to connect to media container service");
1246                         }
1247                     } else if (mPendingInstalls.size() > 0) {
1248                         HandlerParams params = mPendingInstalls.get(0);
1249                         if (params != null) {
1250                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1251                                     System.identityHashCode(params));
1252                             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1253                             if (params.startCopy()) {
1254                                 // We are done...  look for more work or to
1255                                 // go idle.
1256                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
1257                                         "Checking for more work or unbind...");
1258                                 // Delete pending install
1259                                 if (mPendingInstalls.size() > 0) {
1260                                     mPendingInstalls.remove(0);
1261                                 }
1262                                 if (mPendingInstalls.size() == 0) {
1263                                     if (mBound) {
1264                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
1265                                                 "Posting delayed MCS_UNBIND");
1266                                         removeMessages(MCS_UNBIND);
1267                                         Message ubmsg = obtainMessage(MCS_UNBIND);
1268                                         // Unbind after a little delay, to avoid
1269                                         // continual thrashing.
1270                                         sendMessageDelayed(ubmsg, 10000);
1271                                     }
1272                                 } else {
1273                                     // There are more pending requests in queue.
1274                                     // Just post MCS_BOUND message to trigger processing
1275                                     // of next pending install.
1276                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
1277                                             "Posting MCS_BOUND for next work");
1278                                     mHandler.sendEmptyMessage(MCS_BOUND);
1279                                 }
1280                             }
1281                             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1282                         }
1283                     } else {
1284                         // Should never happen ideally.
1285                         Slog.w(TAG, "Empty queue");
1286                     }
1287                     break;
1288                 }
1289                 case MCS_RECONNECT: {
1290                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1291                     if (mPendingInstalls.size() > 0) {
1292                         if (mBound) {
1293                             disconnectService();
1294                         }
1295                         if (!connectToService()) {
1296                             Slog.e(TAG, "Failed to bind to media container service");
1297                             for (HandlerParams params : mPendingInstalls) {
1298                                 // Indicate service bind error
1299                                 params.serviceError();
1300                                 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1301                                         System.identityHashCode(params));
1302                             }
1303                             mPendingInstalls.clear();
1304                         }
1305                     }
1306                     break;
1307                 }
1308                 case MCS_UNBIND: {
1309                     // If there is no actual work left, then time to unbind.
1310                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1311
1312                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1313                         if (mBound) {
1314                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1315
1316                             disconnectService();
1317                         }
1318                     } else if (mPendingInstalls.size() > 0) {
1319                         // There are more pending requests in queue.
1320                         // Just post MCS_BOUND message to trigger processing
1321                         // of next pending install.
1322                         mHandler.sendEmptyMessage(MCS_BOUND);
1323                     }
1324
1325                     break;
1326                 }
1327                 case MCS_GIVE_UP: {
1328                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1329                     HandlerParams params = mPendingInstalls.remove(0);
1330                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1331                             System.identityHashCode(params));
1332                     break;
1333                 }
1334                 case SEND_PENDING_BROADCAST: {
1335                     String packages[];
1336                     ArrayList<String> components[];
1337                     int size = 0;
1338                     int uids[];
1339                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1340                     synchronized (mPackages) {
1341                         if (mPendingBroadcasts == null) {
1342                             return;
1343                         }
1344                         size = mPendingBroadcasts.size();
1345                         if (size <= 0) {
1346                             // Nothing to be done. Just return
1347                             return;
1348                         }
1349                         packages = new String[size];
1350                         components = new ArrayList[size];
1351                         uids = new int[size];
1352                         int i = 0;  // filling out the above arrays
1353
1354                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1355                             int packageUserId = mPendingBroadcasts.userIdAt(n);
1356                             Iterator<Map.Entry<String, ArrayList<String>>> it
1357                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
1358                                             .entrySet().iterator();
1359                             while (it.hasNext() && i < size) {
1360                                 Map.Entry<String, ArrayList<String>> ent = it.next();
1361                                 packages[i] = ent.getKey();
1362                                 components[i] = ent.getValue();
1363                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1364                                 uids[i] = (ps != null)
1365                                         ? UserHandle.getUid(packageUserId, ps.appId)
1366                                         : -1;
1367                                 i++;
1368                             }
1369                         }
1370                         size = i;
1371                         mPendingBroadcasts.clear();
1372                     }
1373                     // Send broadcasts
1374                     for (int i = 0; i < size; i++) {
1375                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1376                     }
1377                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1378                     break;
1379                 }
1380                 case START_CLEANING_PACKAGE: {
1381                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1382                     final String packageName = (String)msg.obj;
1383                     final int userId = msg.arg1;
1384                     final boolean andCode = msg.arg2 != 0;
1385                     synchronized (mPackages) {
1386                         if (userId == UserHandle.USER_ALL) {
1387                             int[] users = sUserManager.getUserIds();
1388                             for (int user : users) {
1389                                 mSettings.addPackageToCleanLPw(
1390                                         new PackageCleanItem(user, packageName, andCode));
1391                             }
1392                         } else {
1393                             mSettings.addPackageToCleanLPw(
1394                                     new PackageCleanItem(userId, packageName, andCode));
1395                         }
1396                     }
1397                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1398                     startCleaningPackages();
1399                 } break;
1400                 case POST_INSTALL: {
1401                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1402
1403                     PostInstallData data = mRunningInstalls.get(msg.arg1);
1404                     final boolean didRestore = (msg.arg2 != 0);
1405                     mRunningInstalls.delete(msg.arg1);
1406
1407                     if (data != null) {
1408                         InstallArgs args = data.args;
1409                         PackageInstalledInfo parentRes = data.res;
1410
1411                         final boolean grantPermissions = (args.installFlags
1412                                 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1413                         final boolean killApp = (args.installFlags
1414                                 & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1415                         final String[] grantedPermissions = args.installGrantPermissions;
1416
1417                         // Handle the parent package
1418                         handlePackagePostInstall(parentRes, grantPermissions, killApp,
1419                                 grantedPermissions, didRestore, args.installerPackageName,
1420                                 args.observer);
1421
1422                         // Handle the child packages
1423                         final int childCount = (parentRes.addedChildPackages != null)
1424                                 ? parentRes.addedChildPackages.size() : 0;
1425                         for (int i = 0; i < childCount; i++) {
1426                             PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1427                             handlePackagePostInstall(childRes, grantPermissions, killApp,
1428                                     grantedPermissions, false, args.installerPackageName,
1429                                     args.observer);
1430                         }
1431
1432                         // Log tracing if needed
1433                         if (args.traceMethod != null) {
1434                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1435                                     args.traceCookie);
1436                         }
1437                     } else {
1438                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1439                     }
1440
1441                     Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1442                 } break;
1443                 case UPDATED_MEDIA_STATUS: {
1444                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1445                     boolean reportStatus = msg.arg1 == 1;
1446                     boolean doGc = msg.arg2 == 1;
1447                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1448                     if (doGc) {
1449                         // Force a gc to clear up stale containers.
1450                         Runtime.getRuntime().gc();
1451                     }
1452                     if (msg.obj != null) {
1453                         @SuppressWarnings("unchecked")
1454                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1455                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1456                         // Unload containers
1457                         unloadAllContainers(args);
1458                     }
1459                     if (reportStatus) {
1460                         try {
1461                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1462                             PackageHelper.getMountService().finishMediaUpdate();
1463                         } catch (RemoteException e) {
1464                             Log.e(TAG, "MountService not running?");
1465                         }
1466                     }
1467                 } break;
1468                 case WRITE_SETTINGS: {
1469                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1470                     synchronized (mPackages) {
1471                         removeMessages(WRITE_SETTINGS);
1472                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1473                         mSettings.writeLPr();
1474                         mDirtyUsers.clear();
1475                     }
1476                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1477                 } break;
1478                 case WRITE_PACKAGE_RESTRICTIONS: {
1479                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1480                     synchronized (mPackages) {
1481                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1482                         for (int userId : mDirtyUsers) {
1483                             mSettings.writePackageRestrictionsLPr(userId);
1484                         }
1485                         mDirtyUsers.clear();
1486                     }
1487                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1488                 } break;
1489                 case WRITE_PACKAGE_LIST: {
1490                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1491                     synchronized (mPackages) {
1492                         removeMessages(WRITE_PACKAGE_LIST);
1493                         mSettings.writePackageListLPr(msg.arg1);
1494                     }
1495                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1496                 } break;
1497                 case CHECK_PENDING_VERIFICATION: {
1498                     final int verificationId = msg.arg1;
1499                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1500
1501                     if ((state != null) && !state.timeoutExtended()) {
1502                         final InstallArgs args = state.getInstallArgs();
1503                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1504
1505                         Slog.i(TAG, "Verification timed out for " + originUri);
1506                         mPendingVerification.remove(verificationId);
1507
1508                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1509
1510                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1511                             Slog.i(TAG, "Continuing with installation of " + originUri);
1512                             state.setVerifierResponse(Binder.getCallingUid(),
1513                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1514                             broadcastPackageVerified(verificationId, originUri,
1515                                     PackageManager.VERIFICATION_ALLOW,
1516                                     state.getInstallArgs().getUser());
1517                             try {
1518                                 ret = args.copyApk(mContainerService, true);
1519                             } catch (RemoteException e) {
1520                                 Slog.e(TAG, "Could not contact the ContainerService");
1521                             }
1522                         } else {
1523                             broadcastPackageVerified(verificationId, originUri,
1524                                     PackageManager.VERIFICATION_REJECT,
1525                                     state.getInstallArgs().getUser());
1526                         }
1527
1528                         Trace.asyncTraceEnd(
1529                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1530
1531                         processPendingInstall(args, ret);
1532                         mHandler.sendEmptyMessage(MCS_UNBIND);
1533                     }
1534                     break;
1535                 }
1536                 case PACKAGE_VERIFIED: {
1537                     final int verificationId = msg.arg1;
1538
1539                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1540                     if (state == null) {
1541                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1542                         break;
1543                     }
1544
1545                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1546
1547                     state.setVerifierResponse(response.callerUid, response.code);
1548
1549                     if (state.isVerificationComplete()) {
1550                         mPendingVerification.remove(verificationId);
1551
1552                         final InstallArgs args = state.getInstallArgs();
1553                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1554
1555                         int ret;
1556                         if (state.isInstallAllowed()) {
1557                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1558                             broadcastPackageVerified(verificationId, originUri,
1559                                     response.code, state.getInstallArgs().getUser());
1560                             try {
1561                                 ret = args.copyApk(mContainerService, true);
1562                             } catch (RemoteException e) {
1563                                 Slog.e(TAG, "Could not contact the ContainerService");
1564                             }
1565                         } else {
1566                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1567                         }
1568
1569                         Trace.asyncTraceEnd(
1570                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1571
1572                         processPendingInstall(args, ret);
1573                         mHandler.sendEmptyMessage(MCS_UNBIND);
1574                     }
1575
1576                     break;
1577                 }
1578                 case START_INTENT_FILTER_VERIFICATIONS: {
1579                     IFVerificationParams params = (IFVerificationParams) msg.obj;
1580                     verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1581                             params.replacing, params.pkg);
1582                     break;
1583                 }
1584                 case INTENT_FILTER_VERIFIED: {
1585                     final int verificationId = msg.arg1;
1586
1587                     final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1588                             verificationId);
1589                     if (state == null) {
1590                         Slog.w(TAG, "Invalid IntentFilter verification token "
1591                                 + verificationId + " received");
1592                         break;
1593                     }
1594
1595                     final int userId = state.getUserId();
1596
1597                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1598                             "Processing IntentFilter verification with token:"
1599                             + verificationId + " and userId:" + userId);
1600
1601                     final IntentFilterVerificationResponse response =
1602                             (IntentFilterVerificationResponse) msg.obj;
1603
1604                     state.setVerifierResponse(response.callerUid, response.code);
1605
1606                     if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1607                             "IntentFilter verification with token:" + verificationId
1608                             + " and userId:" + userId
1609                             + " is settings verifier response with response code:"
1610                             + response.code);
1611
1612                     if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1613                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1614                                 + response.getFailedDomainsString());
1615                     }
1616
1617                     if (state.isVerificationComplete()) {
1618                         mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1619                     } else {
1620                         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1621                                 "IntentFilter verification with token:" + verificationId
1622                                 + " was not said to be complete");
1623                     }
1624
1625                     break;
1626                 }
1627             }
1628         }
1629     }
1630
1631     private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1632             boolean killApp, String[] grantedPermissions,
1633             boolean launchedForRestore, String installerPackage,
1634             IPackageInstallObserver2 installObserver) {
1635         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1636             // Send the removed broadcasts
1637             if (res.removedInfo != null) {
1638                 res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1639             }
1640
1641             // Now that we successfully installed the package, grant runtime
1642             // permissions if requested before broadcasting the install.
1643             if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion
1644                     >= Build.VERSION_CODES.M) {
1645                 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1646             }
1647
1648             final boolean update = res.removedInfo != null
1649                     && res.removedInfo.removedPackage != null;
1650
1651             // If this is the first time we have child packages for a disabled privileged
1652             // app that had no children, we grant requested runtime permissions to the new
1653             // children if the parent on the system image had them already granted.
1654             if (res.pkg.parentPackage != null) {
1655                 synchronized (mPackages) {
1656                     grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1657                 }
1658             }
1659
1660             synchronized (mPackages) {
1661                 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
1662             }
1663
1664             final String packageName = res.pkg.applicationInfo.packageName;
1665             Bundle extras = new Bundle(1);
1666             extras.putInt(Intent.EXTRA_UID, res.uid);
1667
1668             // Determine the set of users who are adding this package for
1669             // the first time vs. those who are seeing an update.
1670             int[] firstUsers = EMPTY_INT_ARRAY;
1671             int[] updateUsers = EMPTY_INT_ARRAY;
1672             if (res.origUsers == null || res.origUsers.length == 0) {
1673                 firstUsers = res.newUsers;
1674             } else {
1675                 for (int newUser : res.newUsers) {
1676                     boolean isNew = true;
1677                     for (int origUser : res.origUsers) {
1678                         if (origUser == newUser) {
1679                             isNew = false;
1680                             break;
1681                         }
1682                     }
1683                     if (isNew) {
1684                         firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1685                     } else {
1686                         updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1687                     }
1688                 }
1689             }
1690
1691             // Send installed broadcasts if the install/update is not ephemeral
1692             if (!isEphemeral(res.pkg)) {
1693                 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1694
1695                 // Send added for users that see the package for the first time
1696                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1697                         extras, 0 /*flags*/, null /*targetPackage*/,
1698                         null /*finishedReceiver*/, firstUsers);
1699
1700                 // Send added for users that don't see the package for the first time
1701                 if (update) {
1702                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
1703                 }
1704                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1705                         extras, 0 /*flags*/, null /*targetPackage*/,
1706                         null /*finishedReceiver*/, updateUsers);
1707
1708                 // Send replaced for users that don't see the package for the first time
1709                 if (update) {
1710                     sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1711                             packageName, extras, 0 /*flags*/,
1712                             null /*targetPackage*/, null /*finishedReceiver*/,
1713                             updateUsers);
1714                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1715                             null /*package*/, null /*extras*/, 0 /*flags*/,
1716                             packageName /*targetPackage*/,
1717                             null /*finishedReceiver*/, updateUsers);
1718                 } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1719                     // First-install and we did a restore, so we're responsible for the
1720                     // first-launch broadcast.
1721                     if (DEBUG_BACKUP) {
1722                         Slog.i(TAG, "Post-restore of " + packageName
1723                                 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1724                     }
1725                     sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1726                 }
1727
1728                 // Send broadcast package appeared if forward locked/external for all users
1729                 // treat asec-hosted packages like removable media on upgrade
1730                 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1731                     if (DEBUG_INSTALL) {
1732                         Slog.i(TAG, "upgrading pkg " + res.pkg
1733                                 + " is ASEC-hosted -> AVAILABLE");
1734                     }
1735                     final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1736                     ArrayList<String> pkgList = new ArrayList<>(1);
1737                     pkgList.add(packageName);
1738                     sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1739                 }
1740             }
1741
1742             // Work that needs to happen on first install within each user
1743             if (firstUsers != null && firstUsers.length > 0) {
1744                 synchronized (mPackages) {
1745                     for (int userId : firstUsers) {
1746                         // If this app is a browser and it's newly-installed for some
1747                         // users, clear any default-browser state in those users. The
1748                         // app's nature doesn't depend on the user, so we can just check
1749                         // its browser nature in any user and generalize.
1750                         if (packageIsBrowser(packageName, userId)) {
1751                             mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1752                         }
1753
1754                         // We may also need to apply pending (restored) runtime
1755                         // permission grants within these users.
1756                         mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1757                     }
1758                 }
1759             }
1760
1761             // Log current value of "unknown sources" setting
1762             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1763                     getUnknownSourcesSettings());
1764
1765             // Force a gc to clear up things
1766             Runtime.getRuntime().gc();
1767
1768             // Remove the replaced package's older resources safely now
1769             // We delete after a gc for applications  on sdcard.
1770             if (res.removedInfo != null && res.removedInfo.args != null) {
1771                 synchronized (mInstallLock) {
1772                     res.removedInfo.args.doPostDeleteLI(true);
1773                 }
1774             }
1775         }
1776
1777         // If someone is watching installs - notify them
1778         if (installObserver != null) {
1779             try {
1780                 Bundle extras = extrasForInstallResult(res);
1781                 installObserver.onPackageInstalled(res.name, res.returnCode,
1782                         res.returnMsg, extras);
1783             } catch (RemoteException e) {
1784                 Slog.i(TAG, "Observer no longer exists.");
1785             }
1786         }
1787     }
1788
1789     private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1790             PackageParser.Package pkg) {
1791         if (pkg.parentPackage == null) {
1792             return;
1793         }
1794         if (pkg.requestedPermissions == null) {
1795             return;
1796         }
1797         final PackageSetting disabledSysParentPs = mSettings
1798                 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1799         if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1800                 || !disabledSysParentPs.isPrivileged()
1801                 || (disabledSysParentPs.childPackageNames != null
1802                         && !disabledSysParentPs.childPackageNames.isEmpty())) {
1803             return;
1804         }
1805         final int[] allUserIds = sUserManager.getUserIds();
1806         final int permCount = pkg.requestedPermissions.size();
1807         for (int i = 0; i < permCount; i++) {
1808             String permission = pkg.requestedPermissions.get(i);
1809             BasePermission bp = mSettings.mPermissions.get(permission);
1810             if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1811                 continue;
1812             }
1813             for (int userId : allUserIds) {
1814                 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1815                         permission, userId)) {
1816                     grantRuntimePermission(pkg.packageName, permission, userId);
1817                 }
1818             }
1819         }
1820     }
1821
1822     private StorageEventListener mStorageListener = new StorageEventListener() {
1823         @Override
1824         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1825             if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1826                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1827                     final String volumeUuid = vol.getFsUuid();
1828
1829                     // Clean up any users or apps that were removed or recreated
1830                     // while this volume was missing
1831                     reconcileUsers(volumeUuid);
1832                     reconcileApps(volumeUuid);
1833
1834                     // Clean up any install sessions that expired or were
1835                     // cancelled while this volume was missing
1836                     mInstallerService.onPrivateVolumeMounted(volumeUuid);
1837
1838                     loadPrivatePackages(vol);
1839
1840                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1841                     unloadPrivatePackages(vol);
1842                 }
1843             }
1844
1845             if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1846                 if (vol.state == VolumeInfo.STATE_MOUNTED) {
1847                     updateExternalMediaStatus(true, false);
1848                 } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1849                     updateExternalMediaStatus(false, false);
1850                 }
1851             }
1852         }
1853
1854         @Override
1855         public void onVolumeForgotten(String fsUuid) {
1856             if (TextUtils.isEmpty(fsUuid)) {
1857                 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1858                 return;
1859             }
1860
1861             // Remove any apps installed on the forgotten volume
1862             synchronized (mPackages) {
1863                 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1864                 for (PackageSetting ps : packages) {
1865                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1866                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1867                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1868                 }
1869
1870                 mSettings.onVolumeForgotten(fsUuid);
1871                 mSettings.writeLPr();
1872             }
1873         }
1874     };
1875
1876     private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1877             String[] grantedPermissions) {
1878         for (int userId : userIds) {
1879             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1880         }
1881
1882         // We could have touched GID membership, so flush out packages.list
1883         synchronized (mPackages) {
1884             mSettings.writePackageListLPr();
1885         }
1886     }
1887
1888     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1889             String[] grantedPermissions) {
1890         SettingBase sb = (SettingBase) pkg.mExtras;
1891         if (sb == null) {
1892             return;
1893         }
1894
1895         PermissionsState permissionsState = sb.getPermissionsState();
1896
1897         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1898                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1899
1900         for (String permission : pkg.requestedPermissions) {
1901             final BasePermission bp;
1902             synchronized (mPackages) {
1903                 bp = mSettings.mPermissions.get(permission);
1904             }
1905             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1906                     && (grantedPermissions == null
1907                            || ArrayUtils.contains(grantedPermissions, permission))) {
1908                 final int flags = permissionsState.getPermissionFlags(permission, userId);
1909                 // Installer cannot change immutable permissions.
1910                 if ((flags & immutableFlags) == 0) {
1911                     grantRuntimePermission(pkg.packageName, permission, userId);
1912                 }
1913             }
1914         }
1915     }
1916
1917     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1918         Bundle extras = null;
1919         switch (res.returnCode) {
1920             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1921                 extras = new Bundle();
1922                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1923                         res.origPermission);
1924                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1925                         res.origPackage);
1926                 break;
1927             }
1928             case PackageManager.INSTALL_SUCCEEDED: {
1929                 extras = new Bundle();
1930                 extras.putBoolean(Intent.EXTRA_REPLACING,
1931                         res.removedInfo != null && res.removedInfo.removedPackage != null);
1932                 break;
1933             }
1934         }
1935         return extras;
1936     }
1937
1938     void scheduleWriteSettingsLocked() {
1939         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1940             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1941         }
1942     }
1943
1944     void scheduleWritePackageListLocked(int userId) {
1945         if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
1946             Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
1947             msg.arg1 = userId;
1948             mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
1949         }
1950     }
1951
1952     void scheduleWritePackageRestrictionsLocked(UserHandle user) {
1953         final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
1954         scheduleWritePackageRestrictionsLocked(userId);
1955     }
1956
1957     void scheduleWritePackageRestrictionsLocked(int userId) {
1958         final int[] userIds = (userId == UserHandle.USER_ALL)
1959                 ? sUserManager.getUserIds() : new int[]{userId};
1960         for (int nextUserId : userIds) {
1961             if (!sUserManager.exists(nextUserId)) return;
1962             mDirtyUsers.add(nextUserId);
1963             if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1964                 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1965             }
1966         }
1967     }
1968
1969     public static PackageManagerService main(Context context, Installer installer,
1970             boolean factoryTest, boolean onlyCore) {
1971         // Self-check for initial settings.
1972         PackageManagerServiceCompilerMapping.checkProperties();
1973
1974         PackageManagerService m = new PackageManagerService(context, installer,
1975                 factoryTest, onlyCore);
1976         m.enableSystemUserPackages();
1977         ServiceManager.addService("package", m);
1978         return m;
1979     }
1980
1981     private void enableSystemUserPackages() {
1982         if (!UserManager.isSplitSystemUser()) {
1983             return;
1984         }
1985         // For system user, enable apps based on the following conditions:
1986         // - app is whitelisted or belong to one of these groups:
1987         //   -- system app which has no launcher icons
1988         //   -- system app which has INTERACT_ACROSS_USERS permission
1989         //   -- system IME app
1990         // - app is not in the blacklist
1991         AppsQueryHelper queryHelper = new AppsQueryHelper(this);
1992         Set<String> enableApps = new ArraySet<>();
1993         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
1994                 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
1995                 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
1996         ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
1997         enableApps.addAll(wlApps);
1998         enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
1999                 /* systemAppsOnly */ false, UserHandle.SYSTEM));
2000         ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2001         enableApps.removeAll(blApps);
2002         Log.i(TAG, "Applications installed for system user: " + enableApps);
2003         List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2004                 UserHandle.SYSTEM);
2005         final int allAppsSize = allAps.size();
2006         synchronized (mPackages) {
2007             for (int i = 0; i < allAppsSize; i++) {
2008                 String pName = allAps.get(i);
2009                 PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2010                 // Should not happen, but we shouldn't be failing if it does
2011                 if (pkgSetting == null) {
2012                     continue;
2013                 }
2014                 boolean install = enableApps.contains(pName);
2015                 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2016                     Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2017                             + " for system user");
2018                     pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2019                 }
2020             }
2021         }
2022     }
2023
2024     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2025         DisplayManager displayManager = (DisplayManager) context.getSystemService(
2026                 Context.DISPLAY_SERVICE);
2027         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2028     }
2029
2030     /**
2031      * Requests that files preopted on a secondary system partition be copied to the data partition
2032      * if possible.  Note that the actual copying of the files is accomplished by init for security
2033      * reasons. This simply requests that the copy takes place and awaits confirmation of its
2034      * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2035      */
2036     private static void requestCopyPreoptedFiles() {
2037         final int WAIT_TIME_MS = 100;
2038         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2039         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2040             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2041             // We will wait for up to 100 seconds.
2042             final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000;
2043             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2044                 try {
2045                     Thread.sleep(WAIT_TIME_MS);
2046                 } catch (InterruptedException e) {
2047                     // Do nothing
2048                 }
2049                 if (SystemClock.uptimeMillis() > timeEnd) {
2050                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2051                     Slog.wtf(TAG, "cppreopt did not finish!");
2052                     break;
2053                 }
2054             }
2055         }
2056     }
2057
2058     public PackageManagerService(Context context, Installer installer,
2059             boolean factoryTest, boolean onlyCore) {
2060         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2061                 SystemClock.uptimeMillis());
2062
2063         if (mSdkVersion <= 0) {
2064             Slog.w(TAG, "**** ro.build.version.sdk not set!");
2065         }
2066
2067         mContext = context;
2068         mFactoryTest = factoryTest;
2069         mOnlyCore = onlyCore;
2070         mMetrics = new DisplayMetrics();
2071         mSettings = new Settings(mPackages);
2072         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2073                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2074         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2075                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2076         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2077                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2078         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2079                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2080         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2081                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2082         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2083                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2084
2085         String separateProcesses = SystemProperties.get("debug.separate_processes");
2086         if (separateProcesses != null && separateProcesses.length() > 0) {
2087             if ("*".equals(separateProcesses)) {
2088                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2089                 mSeparateProcesses = null;
2090                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2091             } else {
2092                 mDefParseFlags = 0;
2093                 mSeparateProcesses = separateProcesses.split(",");
2094                 Slog.w(TAG, "Running with debug.separate_processes: "
2095                         + separateProcesses);
2096             }
2097         } else {
2098             mDefParseFlags = 0;
2099             mSeparateProcesses = null;
2100         }
2101
2102         mInstaller = installer;
2103         mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2104                 "*dexopt*");
2105         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2106
2107         mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2108                 FgThread.get().getLooper());
2109
2110         getDefaultDisplayMetrics(context, mMetrics);
2111
2112         SystemConfig systemConfig = SystemConfig.getInstance();
2113         mGlobalGids = systemConfig.getGlobalGids();
2114         mSystemPermissions = systemConfig.getSystemPermissions();
2115         mAvailableFeatures = systemConfig.getAvailableFeatures();
2116
2117         mProtectedPackages = new ProtectedPackages(mContext);
2118
2119         synchronized (mInstallLock) {
2120         // writer
2121         synchronized (mPackages) {
2122             mHandlerThread = new ServiceThread(TAG,
2123                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2124             mHandlerThread.start();
2125             mHandler = new PackageHandler(mHandlerThread.getLooper());
2126             mProcessLoggingHandler = new ProcessLoggingHandler();
2127             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2128
2129             mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2130
2131             File dataDir = Environment.getDataDirectory();
2132             mAppInstallDir = new File(dataDir, "app");
2133             mAppLib32InstallDir = new File(dataDir, "app-lib");
2134             mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
2135             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2136             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2137
2138             sUserManager = new UserManagerService(context, this, mPackages);
2139
2140             // Propagate permission configuration in to package manager.
2141             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2142                     = systemConfig.getPermissions();
2143             for (int i=0; i<permConfig.size(); i++) {
2144                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2145                 BasePermission bp = mSettings.mPermissions.get(perm.name);
2146                 if (bp == null) {
2147                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2148                     mSettings.mPermissions.put(perm.name, bp);
2149                 }
2150                 if (perm.gids != null) {
2151                     bp.setGids(perm.gids, perm.perUser);
2152                 }
2153             }
2154
2155             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2156             for (int i=0; i<libConfig.size(); i++) {
2157                 mSharedLibraries.put(libConfig.keyAt(i),
2158                         new SharedLibraryEntry(libConfig.valueAt(i), null));
2159             }
2160
2161             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2162
2163             mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2164
2165             // Clean up orphaned packages for which the code path doesn't exist
2166             // and they are an update to a system app - caused by bug/32321269
2167             final int packageSettingCount = mSettings.mPackages.size();
2168             for (int i = packageSettingCount - 1; i >= 0; i--) {
2169                 PackageSetting ps = mSettings.mPackages.valueAt(i);
2170                 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2171                         && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2172                     mSettings.mPackages.removeAt(i);
2173                     mSettings.enableSystemPackageLPw(ps.name);
2174                 }
2175             }
2176
2177             if (mFirstBoot) {
2178                 requestCopyPreoptedFiles();
2179             }
2180
2181             String customResolverActivity = Resources.getSystem().getString(
2182                     R.string.config_customResolverActivity);
2183             if (TextUtils.isEmpty(customResolverActivity)) {
2184                 customResolverActivity = null;
2185             } else {
2186                 mCustomResolverComponentName = ComponentName.unflattenFromString(
2187                         customResolverActivity);
2188             }
2189
2190             long startTime = SystemClock.uptimeMillis();
2191
2192             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2193                     startTime);
2194
2195             // Set flag to monitor and not change apk file paths when
2196             // scanning install directories.
2197             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
2198
2199             final String bootClassPath = System.getenv("BOOTCLASSPATH");
2200             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2201
2202             if (bootClassPath == null) {
2203                 Slog.w(TAG, "No BOOTCLASSPATH found!");
2204             }
2205
2206             if (systemServerClassPath == null) {
2207                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2208             }
2209
2210             final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2211             final String[] dexCodeInstructionSets =
2212                     getDexCodeInstructionSets(
2213                             allInstructionSets.toArray(new String[allInstructionSets.size()]));
2214
2215             /**
2216              * Ensure all external libraries have had dexopt run on them.
2217              */
2218             if (mSharedLibraries.size() > 0) {
2219                 // NOTE: For now, we're compiling these system "shared libraries"
2220                 // (and framework jars) into all available architectures. It's possible
2221                 // to compile them only when we come across an app that uses them (there's
2222                 // already logic for that in scanPackageLI) but that adds some complexity.
2223                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2224                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
2225                         final String lib = libEntry.path;
2226                         if (lib == null) {
2227                             continue;
2228                         }
2229
2230                         try {
2231                             // Shared libraries do not have profiles so we perform a full
2232                             // AOT compilation (if needed).
2233                             int dexoptNeeded = DexFile.getDexOptNeeded(
2234                                     lib, dexCodeInstructionSet,
2235                                     getCompilerFilterForReason(REASON_SHARED_APK),
2236                                     false /* newProfile */);
2237                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2238                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
2239                                         dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
2240                                         getCompilerFilterForReason(REASON_SHARED_APK),
2241                                         StorageManager.UUID_PRIVATE_INTERNAL,
2242                                         SKIP_SHARED_LIBRARY_CHECK);
2243                             }
2244                         } catch (FileNotFoundException e) {
2245                             Slog.w(TAG, "Library not found: " + lib);
2246                         } catch (IOException | InstallerException e) {
2247                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
2248                                     + e.getMessage());
2249                         }
2250                     }
2251                 }
2252             }
2253
2254             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2255
2256             final VersionInfo ver = mSettings.getInternalVersion();
2257             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2258
2259             // when upgrading from pre-M, promote system app permissions from install to runtime
2260             mPromoteSystemApps =
2261                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2262
2263             // When upgrading from pre-N, we need to handle package extraction like first boot,
2264             // as there is no profiling data available.
2265             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2266
2267             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2268
2269             // save off the names of pre-existing system packages prior to scanning; we don't
2270             // want to automatically grant runtime permissions for new system apps
2271             if (mPromoteSystemApps) {
2272                 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2273                 while (pkgSettingIter.hasNext()) {
2274                     PackageSetting ps = pkgSettingIter.next();
2275                     if (isSystemApp(ps)) {
2276                         mExistingSystemPackages.add(ps.name);
2277                     }
2278                 }
2279             }
2280
2281             // Collect vendor overlay packages.
2282             // (Do this before scanning any apps.)
2283             // For security and version matching reason, only consider
2284             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
2285             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
2286             scanDirTracedLI(vendorOverlayDir, mDefParseFlags
2287                     | PackageParser.PARSE_IS_SYSTEM
2288                     | PackageParser.PARSE_IS_SYSTEM_DIR
2289                     | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2290
2291             // Find base frameworks (resource packages without code).
2292             scanDirTracedLI(frameworkDir, mDefParseFlags
2293                     | PackageParser.PARSE_IS_SYSTEM
2294                     | PackageParser.PARSE_IS_SYSTEM_DIR
2295                     | PackageParser.PARSE_IS_PRIVILEGED,
2296                     scanFlags | SCAN_NO_DEX, 0);
2297
2298             // Collected privileged system packages.
2299             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2300             scanDirTracedLI(privilegedAppDir, mDefParseFlags
2301                     | PackageParser.PARSE_IS_SYSTEM
2302                     | PackageParser.PARSE_IS_SYSTEM_DIR
2303                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2304
2305             // Collect ordinary system packages.
2306             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2307             scanDirTracedLI(systemAppDir, mDefParseFlags
2308                     | PackageParser.PARSE_IS_SYSTEM
2309                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2310
2311             // Collect all vendor packages.
2312             File vendorAppDir = new File("/vendor/app");
2313             try {
2314                 vendorAppDir = vendorAppDir.getCanonicalFile();
2315             } catch (IOException e) {
2316                 // failed to look up canonical path, continue with original one
2317             }
2318             scanDirTracedLI(vendorAppDir, mDefParseFlags
2319                     | PackageParser.PARSE_IS_SYSTEM
2320                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2321
2322             // Collect all OEM packages.
2323             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2324             scanDirTracedLI(oemAppDir, mDefParseFlags
2325                     | PackageParser.PARSE_IS_SYSTEM
2326                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2327
2328             // Prune any system packages that no longer exist.
2329             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2330             if (!mOnlyCore) {
2331                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2332                 while (psit.hasNext()) {
2333                     PackageSetting ps = psit.next();
2334
2335                     /*
2336                      * If this is not a system app, it can't be a
2337                      * disable system app.
2338                      */
2339                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2340                         continue;
2341                     }
2342
2343                     /*
2344                      * If the package is scanned, it's not erased.
2345                      */
2346                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2347                     if (scannedPkg != null) {
2348                         /*
2349                          * If the system app is both scanned and in the
2350                          * disabled packages list, then it must have been
2351                          * added via OTA. Remove it from the currently
2352                          * scanned package so the previously user-installed
2353                          * application can be scanned.
2354                          */
2355                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2356                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2357                                     + ps.name + "; removing system app.  Last known codePath="
2358                                     + ps.codePathString + ", installStatus=" + ps.installStatus
2359                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2360                                     + scannedPkg.mVersionCode);
2361                             removePackageLI(scannedPkg, true);
2362                             mExpectingBetter.put(ps.name, ps.codePath);
2363                         }
2364
2365                         continue;
2366                     }
2367
2368                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2369                         psit.remove();
2370                         logCriticalInfo(Log.WARN, "System package " + ps.name
2371                                 + " no longer exists; it's data will be wiped");
2372                         // Actual deletion of code and data will be handled by later
2373                         // reconciliation step
2374                     } else {
2375                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2376                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2377                             possiblyDeletedUpdatedSystemApps.add(ps.name);
2378                         }
2379                     }
2380                 }
2381             }
2382
2383             //look for any incomplete package installations
2384             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2385             for (int i = 0; i < deletePkgsList.size(); i++) {
2386                 // Actual deletion of code and data will be handled by later
2387                 // reconciliation step
2388                 final String packageName = deletePkgsList.get(i).name;
2389                 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2390                 synchronized (mPackages) {
2391                     mSettings.removePackageLPw(packageName);
2392                 }
2393             }
2394
2395             //delete tmp files
2396             deleteTempPackageFiles();
2397
2398             // Remove any shared userIDs that have no associated packages
2399             mSettings.pruneSharedUsersLPw();
2400
2401             if (!mOnlyCore) {
2402                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2403                         SystemClock.uptimeMillis());
2404                 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2405
2406                 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2407                         | PackageParser.PARSE_FORWARD_LOCK,
2408                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2409
2410                 scanDirLI(mEphemeralInstallDir, mDefParseFlags
2411                         | PackageParser.PARSE_IS_EPHEMERAL,
2412                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
2413
2414                 /**
2415                  * Remove disable package settings for any updated system
2416                  * apps that were removed via an OTA. If they're not a
2417                  * previously-updated app, remove them completely.
2418                  * Otherwise, just revoke their system-level permissions.
2419                  */
2420                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2421                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2422                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2423
2424                     String msg;
2425                     if (deletedPkg == null) {
2426                         msg = "Updated system package " + deletedAppName
2427                                 + " no longer exists; it's data will be wiped";
2428                         // Actual deletion of code and data will be handled by later
2429                         // reconciliation step
2430                     } else {
2431                         msg = "Updated system app + " + deletedAppName
2432                                 + " no longer present; removing system privileges for "
2433                                 + deletedAppName;
2434
2435                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2436
2437                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2438                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2439                     }
2440                     logCriticalInfo(Log.WARN, msg);
2441                 }
2442
2443                 /**
2444                  * Make sure all system apps that we expected to appear on
2445                  * the userdata partition actually showed up. If they never
2446                  * appeared, crawl back and revive the system version.
2447                  */
2448                 for (int i = 0; i < mExpectingBetter.size(); i++) {
2449                     final String packageName = mExpectingBetter.keyAt(i);
2450                     if (!mPackages.containsKey(packageName)) {
2451                         final File scanFile = mExpectingBetter.valueAt(i);
2452
2453                         logCriticalInfo(Log.WARN, "Expected better " + packageName
2454                                 + " but never showed up; reverting to system");
2455
2456                         int reparseFlags = mDefParseFlags;
2457                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
2458                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2459                                     | PackageParser.PARSE_IS_SYSTEM_DIR
2460                                     | PackageParser.PARSE_IS_PRIVILEGED;
2461                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
2462                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2463                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2464                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2465                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2466                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2467                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
2468                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
2469                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
2470                         } else {
2471                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2472                             continue;
2473                         }
2474
2475                         mSettings.enableSystemPackageLPw(packageName);
2476
2477                         try {
2478                             scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2479                         } catch (PackageManagerException e) {
2480                             Slog.e(TAG, "Failed to parse original system package: "
2481                                     + e.getMessage());
2482                         }
2483                     }
2484                 }
2485             }
2486             mExpectingBetter.clear();
2487
2488             // Resolve the storage manager.
2489             mStorageManagerPackage = getStorageManagerPackageName();
2490
2491             // Resolve protected action filters. Only the setup wizard is allowed to
2492             // have a high priority filter for these actions.
2493             mSetupWizardPackage = getSetupWizardPackageName();
2494             if (mProtectedFilters.size() > 0) {
2495                 if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2496                     Slog.i(TAG, "No setup wizard;"
2497                         + " All protected intents capped to priority 0");
2498                 }
2499                 for (ActivityIntentInfo filter : mProtectedFilters) {
2500                     if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2501                         if (DEBUG_FILTERS) {
2502                             Slog.i(TAG, "Found setup wizard;"
2503                                 + " allow priority " + filter.getPriority() + ";"
2504                                 + " package: " + filter.activity.info.packageName
2505                                 + " activity: " + filter.activity.className
2506                                 + " priority: " + filter.getPriority());
2507                         }
2508                         // skip setup wizard; allow it to keep the high priority filter
2509                         continue;
2510                     }
2511                     Slog.w(TAG, "Protected action; cap priority to 0;"
2512                             + " package: " + filter.activity.info.packageName
2513                             + " activity: " + filter.activity.className
2514                             + " origPrio: " + filter.getPriority());
2515                     filter.setPriority(0);
2516                 }
2517             }
2518             mDeferProtectedFilters = false;
2519             mProtectedFilters.clear();
2520
2521             // Now that we know all of the shared libraries, update all clients to have
2522             // the correct library paths.
2523             updateAllSharedLibrariesLPw();
2524
2525             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2526                 // NOTE: We ignore potential failures here during a system scan (like
2527                 // the rest of the commands above) because there's precious little we
2528                 // can do about it. A settings error is reported, though.
2529                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2530                         false /* boot complete */);
2531             }
2532
2533             // Now that we know all the packages we are keeping,
2534             // read and update their last usage times.
2535             mPackageUsage.read(mPackages);
2536             mCompilerStats.read();
2537
2538             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2539                     SystemClock.uptimeMillis());
2540             Slog.i(TAG, "Time to scan packages: "
2541                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
2542                     + " seconds");
2543
2544             // If the platform SDK has changed since the last time we booted,
2545             // we need to re-grant app permission to catch any new ones that
2546             // appear.  This is really a hack, and means that apps can in some
2547             // cases get permissions that the user didn't initially explicitly
2548             // allow...  it would be nice to have some better way to handle
2549             // this situation.
2550             int updateFlags = UPDATE_PERMISSIONS_ALL;
2551             if (ver.sdkVersion != mSdkVersion) {
2552                 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2553                         + mSdkVersion + "; regranting permissions for internal storage");
2554                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2555             }
2556             updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2557             ver.sdkVersion = mSdkVersion;
2558
2559             // If this is the first boot or an update from pre-M, and it is a normal
2560             // boot, then we need to initialize the default preferred apps across
2561             // all defined users.
2562             if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2563                 for (UserInfo user : sUserManager.getUsers(true)) {
2564                     mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2565                     applyFactoryDefaultBrowserLPw(user.id);
2566                     primeDomainVerificationsLPw(user.id);
2567                 }
2568             }
2569
2570             // Prepare storage for system user really early during boot,
2571             // since core system apps like SettingsProvider and SystemUI
2572             // can't wait for user to start
2573             final int storageFlags;
2574             if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2575                 storageFlags = StorageManager.FLAG_STORAGE_DE;
2576             } else {
2577                 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2578             }
2579             reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
2580                     storageFlags);
2581
2582             // If this is first boot after an OTA, and a normal boot, then
2583             // we need to clear code cache directories.
2584             // Note that we do *not* clear the application profiles. These remain valid
2585             // across OTAs and are used to drive profile verification (post OTA) and
2586             // profile compilation (without waiting to collect a fresh set of profiles).
2587             if (mIsUpgrade && !onlyCore) {
2588                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2589                 for (int i = 0; i < mSettings.mPackages.size(); i++) {
2590                     final PackageSetting ps = mSettings.mPackages.valueAt(i);
2591                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2592                         // No apps are running this early, so no need to freeze
2593                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2594                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2595                                         | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2596                     }
2597                 }
2598                 ver.fingerprint = Build.FINGERPRINT;
2599             }
2600
2601             checkDefaultBrowser();
2602
2603             // clear only after permissions and other defaults have been updated
2604             mExistingSystemPackages.clear();
2605             mPromoteSystemApps = false;
2606
2607             // All the changes are done during package scanning.
2608             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2609
2610             // can downgrade to reader
2611             mSettings.writeLPr();
2612
2613             // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
2614             // early on (before the package manager declares itself as early) because other
2615             // components in the system server might ask for package contexts for these apps.
2616             //
2617             // Note that "onlyCore" in this context means the system is encrypted or encrypting
2618             // (i.e, that the data partition is unavailable).
2619             if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
2620                 long start = System.nanoTime();
2621                 List<PackageParser.Package> coreApps = new ArrayList<>();
2622                 for (PackageParser.Package pkg : mPackages.values()) {
2623                     if (pkg.coreApp) {
2624                         coreApps.add(pkg);
2625                     }
2626                 }
2627
2628                 int[] stats = performDexOptUpgrade(coreApps, false,
2629                         getCompilerFilterForReason(REASON_CORE_APP));
2630
2631                 final int elapsedTimeSeconds =
2632                         (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
2633                 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
2634
2635                 if (DEBUG_DEXOPT) {
2636                     Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
2637                             stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
2638                 }
2639
2640
2641                 // TODO: Should we log these stats to tron too ?
2642                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
2643                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
2644                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
2645                 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
2646             }
2647
2648             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2649                     SystemClock.uptimeMillis());
2650
2651             if (!mOnlyCore) {
2652                 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2653                 mRequiredInstallerPackage = getRequiredInstallerLPr();
2654                 mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2655                 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2656                 mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2657                         mIntentFilterVerifierComponent);
2658                 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2659                         PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
2660                 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2661                         PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
2662             } else {
2663                 mRequiredVerifierPackage = null;
2664                 mRequiredInstallerPackage = null;
2665                 mRequiredUninstallerPackage = null;
2666                 mIntentFilterVerifierComponent = null;
2667                 mIntentFilterVerifier = null;
2668                 mServicesSystemSharedLibraryPackageName = null;
2669                 mSharedSystemSharedLibraryPackageName = null;
2670             }
2671
2672             mInstallerService = new PackageInstallerService(context, this);
2673
2674             final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2675             final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
2676             // both the installer and resolver must be present to enable ephemeral
2677             if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
2678                 if (DEBUG_EPHEMERAL) {
2679                     Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
2680                             + " installer:" + ephemeralInstallerComponent);
2681                 }
2682                 mEphemeralResolverComponent = ephemeralResolverComponent;
2683                 mEphemeralInstallerComponent = ephemeralInstallerComponent;
2684                 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2685                 mEphemeralResolverConnection =
2686                         new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
2687             } else {
2688                 if (DEBUG_EPHEMERAL) {
2689                     final String missingComponent =
2690                             (ephemeralResolverComponent == null)
2691                             ? (ephemeralInstallerComponent == null)
2692                                     ? "resolver and installer"
2693                                     : "resolver"
2694                             : "installer";
2695                     Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
2696                 }
2697                 mEphemeralResolverComponent = null;
2698                 mEphemeralInstallerComponent = null;
2699                 mEphemeralResolverConnection = null;
2700             }
2701
2702             mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
2703         } // synchronized (mPackages)
2704         } // synchronized (mInstallLock)
2705
2706         // Now after opening every single application zip, make sure they
2707         // are all flushed.  Not really needed, but keeps things nice and
2708         // tidy.
2709         Runtime.getRuntime().gc();
2710
2711         // The initial scanning above does many calls into installd while
2712         // holding the mPackages lock, but we're mostly interested in yelling
2713         // once we have a booted system.
2714         mInstaller.setWarnIfHeld(mPackages);
2715
2716         // Expose private service for system components to use.
2717         LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2718     }
2719
2720     @Override
2721     public boolean isFirstBoot() {
2722         return mFirstBoot;
2723     }
2724
2725     @Override
2726     public boolean isOnlyCoreApps() {
2727         return mOnlyCore;
2728     }
2729
2730     @Override
2731     public boolean isUpgrade() {
2732         return mIsUpgrade;
2733     }
2734
2735     private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2736         final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2737
2738         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2739                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2740                 UserHandle.USER_SYSTEM);
2741         if (matches.size() == 1) {
2742             return matches.get(0).getComponentInfo().packageName;
2743         } else if (matches.size() == 0) {
2744             Log.e(TAG, "There should probably be a verifier, but, none were found");
2745             return null;
2746         }
2747         throw new RuntimeException("There must be exactly one verifier; found " + matches);
2748     }
2749
2750     private @NonNull String getRequiredSharedLibraryLPr(String libraryName) {
2751         synchronized (mPackages) {
2752             SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName);
2753             if (libraryEntry == null) {
2754                 throw new IllegalStateException("Missing required shared library:" + libraryName);
2755             }
2756             return libraryEntry.apk;
2757         }
2758     }
2759
2760     private @NonNull String getRequiredInstallerLPr() {
2761         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2762         intent.addCategory(Intent.CATEGORY_DEFAULT);
2763         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2764
2765         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2766                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2767                 UserHandle.USER_SYSTEM);
2768         if (matches.size() == 1) {
2769             ResolveInfo resolveInfo = matches.get(0);
2770             if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
2771                 throw new RuntimeException("The installer must be a privileged app");
2772             }
2773             return matches.get(0).getComponentInfo().packageName;
2774         } else {
2775             throw new RuntimeException("There must be exactly one installer; found " + matches);
2776         }
2777     }
2778
2779     private @NonNull String getRequiredUninstallerLPr() {
2780         final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
2781         intent.addCategory(Intent.CATEGORY_DEFAULT);
2782         intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
2783
2784         final ResolveInfo resolveInfo = resolveIntent(intent, null,
2785                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2786                 UserHandle.USER_SYSTEM);
2787         if (resolveInfo == null ||
2788                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
2789             throw new RuntimeException("There must be exactly one uninstaller; found "
2790                     + resolveInfo);
2791         }
2792         return resolveInfo.getComponentInfo().packageName;
2793     }
2794
2795     private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2796         final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2797
2798         final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2799                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2800                 UserHandle.USER_SYSTEM);
2801         ResolveInfo best = null;
2802         final int N = matches.size();
2803         for (int i = 0; i < N; i++) {
2804             final ResolveInfo cur = matches.get(i);
2805             final String packageName = cur.getComponentInfo().packageName;
2806             if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2807                     packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2808                 continue;
2809             }
2810
2811             if (best == null || cur.priority > best.priority) {
2812                 best = cur;
2813             }
2814         }
2815
2816         if (best != null) {
2817             return best.getComponentInfo().getComponentName();
2818         } else {
2819             throw new RuntimeException("There must be at least one intent filter verifier");
2820         }
2821     }
2822
2823     private @Nullable ComponentName getEphemeralResolverLPr() {
2824         final String[] packageArray =
2825                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2826         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
2827             if (DEBUG_EPHEMERAL) {
2828                 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2829             }
2830             return null;
2831         }
2832
2833         final int resolveFlags =
2834                 MATCH_DIRECT_BOOT_AWARE
2835                 | MATCH_DIRECT_BOOT_UNAWARE
2836                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2837         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2838         final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
2839                 resolveFlags, UserHandle.USER_SYSTEM);
2840
2841         final int N = resolvers.size();
2842         if (N == 0) {
2843             if (DEBUG_EPHEMERAL) {
2844                 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2845             }
2846             return null;
2847         }
2848
2849         final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2850         for (int i = 0; i < N; i++) {
2851             final ResolveInfo info = resolvers.get(i);
2852
2853             if (info.serviceInfo == null) {
2854                 continue;
2855             }
2856
2857             final String packageName = info.serviceInfo.packageName;
2858             if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
2859                 if (DEBUG_EPHEMERAL) {
2860                     Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2861                             + " pkg: " + packageName + ", info:" + info);
2862                 }
2863                 continue;
2864             }
2865
2866             if (DEBUG_EPHEMERAL) {
2867                 Slog.v(TAG, "Ephemeral resolver found;"
2868                         + " pkg: " + packageName + ", info:" + info);
2869             }
2870             return new ComponentName(packageName, info.serviceInfo.name);
2871         }
2872         if (DEBUG_EPHEMERAL) {
2873             Slog.v(TAG, "Ephemeral resolver NOT found");
2874         }
2875         return null;
2876     }
2877
2878     private @Nullable ComponentName getEphemeralInstallerLPr() {
2879         final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2880         intent.addCategory(Intent.CATEGORY_DEFAULT);
2881         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2882
2883         final int resolveFlags =
2884                 MATCH_DIRECT_BOOT_AWARE
2885                 | MATCH_DIRECT_BOOT_UNAWARE
2886                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2887         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2888                 resolveFlags, UserHandle.USER_SYSTEM);
2889         if (matches.size() == 0) {
2890             return null;
2891         } else if (matches.size() == 1) {
2892             return matches.get(0).getComponentInfo().getComponentName();
2893         } else {
2894             throw new RuntimeException(
2895                     "There must be at most one ephemeral installer; found " + matches);
2896         }
2897     }
2898
2899     private void primeDomainVerificationsLPw(int userId) {
2900         if (DEBUG_DOMAIN_VERIFICATION) {
2901             Slog.d(TAG, "Priming domain verifications in user " + userId);
2902         }
2903
2904         SystemConfig systemConfig = SystemConfig.getInstance();
2905         ArraySet<String> packages = systemConfig.getLinkedApps();
2906         ArraySet<String> domains = new ArraySet<String>();
2907
2908         for (String packageName : packages) {
2909             PackageParser.Package pkg = mPackages.get(packageName);
2910             if (pkg != null) {
2911                 if (!pkg.isSystemApp()) {
2912                     Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2913                     continue;
2914                 }
2915
2916                 domains.clear();
2917                 for (PackageParser.Activity a : pkg.activities) {
2918                     for (ActivityIntentInfo filter : a.intents) {
2919                         if (hasValidDomains(filter)) {
2920                             domains.addAll(filter.getHostsList());
2921                         }
2922                     }
2923                 }
2924
2925                 if (domains.size() > 0) {
2926                     if (DEBUG_DOMAIN_VERIFICATION) {
2927                         Slog.v(TAG, "      + " + packageName);
2928                     }
2929                     // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2930                     // state w.r.t. the formal app-linkage "no verification attempted" state;
2931                     // and then 'always' in the per-user state actually used for intent resolution.
2932                     final IntentFilterVerificationInfo ivi;
2933                     ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2934                             new ArrayList<String>(domains));
2935                     ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2936                     mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2937                             INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2938                 } else {
2939                     Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2940                             + "' does not handle web links");
2941                 }
2942             } else {
2943                 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2944             }
2945         }
2946
2947         scheduleWritePackageRestrictionsLocked(userId);
2948         scheduleWriteSettingsLocked();
2949     }
2950
2951     private void applyFactoryDefaultBrowserLPw(int userId) {
2952         // The default browser app's package name is stored in a string resource,
2953         // with a product-specific overlay used for vendor customization.
2954         String browserPkg = mContext.getResources().getString(
2955                 com.android.internal.R.string.default_browser);
2956         if (!TextUtils.isEmpty(browserPkg)) {
2957             // non-empty string => required to be a known package
2958             PackageSetting ps = mSettings.mPackages.get(browserPkg);
2959             if (ps == null) {
2960                 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2961                 browserPkg = null;
2962             } else {
2963                 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2964             }
2965         }
2966
2967         // Nothing valid explicitly set? Make the factory-installed browser the explicit
2968         // default.  If there's more than one, just leave everything alone.
2969         if (browserPkg == null) {
2970             calculateDefaultBrowserLPw(userId);
2971         }
2972     }
2973
2974     private void calculateDefaultBrowserLPw(int userId) {
2975         List<String> allBrowsers = resolveAllBrowserApps(userId);
2976         final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2977         mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2978     }
2979
2980     private List<String> resolveAllBrowserApps(int userId) {
2981         // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2982         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
2983                 PackageManager.MATCH_ALL, userId);
2984
2985         final int count = list.size();
2986         List<String> result = new ArrayList<String>(count);
2987         for (int i=0; i<count; i++) {
2988             ResolveInfo info = list.get(i);
2989             if (info.activityInfo == null
2990                     || !info.handleAllWebDataURI
2991                     || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2992                     || result.contains(info.activityInfo.packageName)) {
2993                 continue;
2994             }
2995             result.add(info.activityInfo.packageName);
2996         }
2997
2998         return result;
2999     }
3000
3001     private boolean packageIsBrowser(String packageName, int userId) {
3002         List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3003                 PackageManager.MATCH_ALL, userId);
3004         final int N = list.size();
3005         for (int i = 0; i < N; i++) {
3006             ResolveInfo info = list.get(i);
3007             if (packageName.equals(info.activityInfo.packageName)) {
3008                 return true;
3009             }
3010         }
3011         return false;
3012     }
3013
3014     private void checkDefaultBrowser() {
3015         final int myUserId = UserHandle.myUserId();
3016         final String packageName = getDefaultBrowserPackageName(myUserId);
3017         if (packageName != null) {
3018             PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3019             if (info == null) {
3020                 Slog.w(TAG, "Default browser no longer installed: " + packageName);
3021                 synchronized (mPackages) {
3022                     applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3023                 }
3024             }
3025         }
3026     }
3027
3028     @Override
3029     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3030             throws RemoteException {
3031         try {
3032             return super.onTransact(code, data, reply, flags);
3033         } catch (RuntimeException e) {
3034             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3035                 Slog.wtf(TAG, "Package Manager Crash", e);
3036             }
3037             throw e;
3038         }
3039     }
3040
3041     static int[] appendInts(int[] cur, int[] add) {
3042         if (add == null) return cur;
3043         if (cur == null) return add;
3044         final int N = add.length;
3045         for (int i=0; i<N; i++) {
3046             cur = appendInt(cur, add[i]);
3047         }
3048         return cur;
3049     }
3050
3051     private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3052         if (!sUserManager.exists(userId)) return null;
3053         if (ps == null) {
3054             return null;
3055         }
3056         final PackageParser.Package p = ps.pkg;
3057         if (p == null) {
3058             return null;
3059         }
3060
3061         final PermissionsState permissionsState = ps.getPermissionsState();
3062
3063         // Compute GIDs only if requested
3064         final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3065                 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3066         // Compute granted permissions only if package has requested permissions
3067         final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3068                 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3069         final PackageUserState state = ps.readUserState(userId);
3070
3071         return PackageParser.generatePackageInfo(p, gids, flags,
3072                 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3073     }
3074
3075     @Override
3076     public void checkPackageStartable(String packageName, int userId) {
3077         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3078
3079         synchronized (mPackages) {
3080             final PackageSetting ps = mSettings.mPackages.get(packageName);
3081             if (ps == null) {
3082                 throw new SecurityException("Package " + packageName + " was not found!");
3083             }
3084
3085             if (!ps.getInstalled(userId)) {
3086                 throw new SecurityException(
3087                         "Package " + packageName + " was not installed for user " + userId + "!");
3088             }
3089
3090             if (mSafeMode && !ps.isSystem()) {
3091                 throw new SecurityException("Package " + packageName + " not a system app!");
3092             }
3093
3094             if (mFrozenPackages.contains(packageName)) {
3095                 throw new SecurityException("Package " + packageName + " is currently frozen!");
3096             }
3097
3098             if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3099                     || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3100                 throw new SecurityException("Package " + packageName + " is not encryption aware!");
3101             }
3102         }
3103     }
3104
3105     @Override
3106     public boolean isPackageAvailable(String packageName, int userId) {
3107         if (!sUserManager.exists(userId)) return false;
3108         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3109                 false /* requireFullPermission */, false /* checkShell */, "is package available");
3110         synchronized (mPackages) {
3111             PackageParser.Package p = mPackages.get(packageName);
3112             if (p != null) {
3113                 final PackageSetting ps = (PackageSetting) p.mExtras;
3114                 if (ps != null) {
3115                     final PackageUserState state = ps.readUserState(userId);
3116                     if (state != null) {
3117                         return PackageParser.isAvailable(state);
3118                     }
3119                 }
3120             }
3121         }
3122         return false;
3123     }
3124
3125     @Override
3126     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3127         if (!sUserManager.exists(userId)) return null;
3128         flags = updateFlagsForPackage(flags, userId, packageName);
3129         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3130                 false /* requireFullPermission */, false /* checkShell */, "get package info");
3131
3132         // reader
3133         synchronized (mPackages) {
3134             // Normalize package name to hanlde renamed packages
3135             packageName = normalizePackageNameLPr(packageName);
3136
3137             final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3138             PackageParser.Package p = null;
3139             if (matchFactoryOnly) {
3140                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3141                 if (ps != null) {
3142                     return generatePackageInfo(ps, flags, userId);
3143                 }
3144             }
3145             if (p == null) {
3146                 p = mPackages.get(packageName);
3147                 if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3148                     return null;
3149                 }
3150             }
3151             if (DEBUG_PACKAGE_INFO)
3152                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3153             if (p != null) {
3154                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3155             }
3156             if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3157                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3158                 return generatePackageInfo(ps, flags, userId);
3159             }
3160         }
3161         return null;
3162     }
3163
3164     @Override
3165     public String[] currentToCanonicalPackageNames(String[] names) {
3166         String[] out = new String[names.length];
3167         // reader
3168         synchronized (mPackages) {
3169             for (int i=names.length-1; i>=0; i--) {
3170                 PackageSetting ps = mSettings.mPackages.get(names[i]);
3171                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3172             }
3173         }
3174         return out;
3175     }
3176
3177     @Override
3178     public String[] canonicalToCurrentPackageNames(String[] names) {
3179         String[] out = new String[names.length];
3180         // reader
3181         synchronized (mPackages) {
3182             for (int i=names.length-1; i>=0; i--) {
3183                 String cur = mSettings.mRenamedPackages.get(names[i]);
3184                 out[i] = cur != null ? cur : names[i];
3185             }
3186         }
3187         return out;
3188     }
3189
3190     @Override
3191     public int getPackageUid(String packageName, int flags, int userId) {
3192         if (!sUserManager.exists(userId)) return -1;
3193         flags = updateFlagsForPackage(flags, userId, packageName);
3194         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3195                 false /* requireFullPermission */, false /* checkShell */, "get package uid");
3196
3197         // reader
3198         synchronized (mPackages) {
3199             final PackageParser.Package p = mPackages.get(packageName);
3200             if (p != null && p.isMatch(flags)) {
3201                 return UserHandle.getUid(userId, p.applicationInfo.uid);
3202             }
3203             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3204                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3205                 if (ps != null && ps.isMatch(flags)) {
3206                     return UserHandle.getUid(userId, ps.appId);
3207                 }
3208             }
3209         }
3210
3211         return -1;
3212     }
3213
3214     @Override
3215     public int[] getPackageGids(String packageName, int flags, int userId) {
3216         if (!sUserManager.exists(userId)) return null;
3217         flags = updateFlagsForPackage(flags, userId, packageName);
3218         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3219                 false /* requireFullPermission */, false /* checkShell */,
3220                 "getPackageGids");
3221
3222         // reader
3223         synchronized (mPackages) {
3224             final PackageParser.Package p = mPackages.get(packageName);
3225             if (p != null && p.isMatch(flags)) {
3226                 PackageSetting ps = (PackageSetting) p.mExtras;
3227                 return ps.getPermissionsState().computeGids(userId);
3228             }
3229             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3230                 final PackageSetting ps = mSettings.mPackages.get(packageName);
3231                 if (ps != null && ps.isMatch(flags)) {
3232                     return ps.getPermissionsState().computeGids(userId);
3233                 }
3234             }
3235         }
3236
3237         return null;
3238     }
3239
3240     static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3241         if (bp.perm != null) {
3242             return PackageParser.generatePermissionInfo(bp.perm, flags);
3243         }
3244         PermissionInfo pi = new PermissionInfo();
3245         pi.name = bp.name;
3246         pi.packageName = bp.sourcePackage;
3247         pi.nonLocalizedLabel = bp.name;
3248         pi.protectionLevel = bp.protectionLevel;
3249         return pi;
3250     }
3251
3252     @Override
3253     public PermissionInfo getPermissionInfo(String name, int flags) {
3254         // reader
3255         synchronized (mPackages) {
3256             final BasePermission p = mSettings.mPermissions.get(name);
3257             if (p != null) {
3258                 return generatePermissionInfo(p, flags);
3259             }
3260             return null;
3261         }
3262     }
3263
3264     @Override
3265     public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3266             int flags) {
3267         // reader
3268         synchronized (mPackages) {
3269             if (group != null && !mPermissionGroups.containsKey(group)) {
3270                 // This is thrown as NameNotFoundException
3271                 return null;
3272             }
3273
3274             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3275             for (BasePermission p : mSettings.mPermissions.values()) {
3276                 if (group == null) {
3277                     if (p.perm == null || p.perm.info.group == null) {
3278                         out.add(generatePermissionInfo(p, flags));
3279                     }
3280                 } else {
3281                     if (p.perm != null && group.equals(p.perm.info.group)) {
3282                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3283                     }
3284                 }
3285             }
3286             return new ParceledListSlice<>(out);
3287         }
3288     }
3289
3290     @Override
3291     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3292         // reader
3293         synchronized (mPackages) {
3294             return PackageParser.generatePermissionGroupInfo(
3295                     mPermissionGroups.get(name), flags);
3296         }
3297     }
3298
3299     @Override
3300     public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3301         // reader
3302         synchronized (mPackages) {
3303             final int N = mPermissionGroups.size();
3304             ArrayList<PermissionGroupInfo> out
3305                     = new ArrayList<PermissionGroupInfo>(N);
3306             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3307                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3308             }
3309             return new ParceledListSlice<>(out);
3310         }
3311     }
3312
3313     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3314             int userId) {
3315         if (!sUserManager.exists(userId)) return null;
3316         PackageSetting ps = mSettings.mPackages.get(packageName);
3317         if (ps != null) {
3318             if (ps.pkg == null) {
3319                 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3320                 if (pInfo != null) {
3321                     return pInfo.applicationInfo;
3322                 }
3323                 return null;
3324             }
3325             return PackageParser.generateApplicationInfo(ps.pkg, flags,
3326                     ps.readUserState(userId), userId);
3327         }
3328         return null;
3329     }
3330
3331     @Override
3332     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3333         if (!sUserManager.exists(userId)) return null;
3334         flags = updateFlagsForApplication(flags, userId, packageName);
3335         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3336                 false /* requireFullPermission */, false /* checkShell */, "get application info");
3337
3338         // writer
3339         synchronized (mPackages) {
3340             // Normalize package name to hanlde renamed packages
3341             packageName = normalizePackageNameLPr(packageName);
3342
3343             PackageParser.Package p = mPackages.get(packageName);
3344             if (DEBUG_PACKAGE_INFO) Log.v(
3345                     TAG, "getApplicationInfo " + packageName
3346                     + ": " + p);
3347             if (p != null) {
3348                 PackageSetting ps = mSettings.mPackages.get(packageName);
3349                 if (ps == null) return null;
3350                 // Note: isEnabledLP() does not apply here - always return info
3351                 return PackageParser.generateApplicationInfo(
3352                         p, flags, ps.readUserState(userId), userId);
3353             }
3354             if ("android".equals(packageName)||"system".equals(packageName)) {
3355                 return mAndroidApplication;
3356             }
3357             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3358                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3359             }
3360         }
3361         return null;
3362     }
3363
3364     private String normalizePackageNameLPr(String packageName) {
3365         String normalizedPackageName = mSettings.mRenamedPackages.get(packageName);
3366         return normalizedPackageName != null ? normalizedPackageName : packageName;
3367     }
3368
3369     @Override
3370     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3371             final IPackageDataObserver observer) {
3372         mContext.enforceCallingOrSelfPermission(
3373                 android.Manifest.permission.CLEAR_APP_CACHE, null);
3374         // Queue up an async operation since clearing cache may take a little while.
3375         mHandler.post(new Runnable() {
3376             public void run() {
3377                 mHandler.removeCallbacks(this);
3378                 boolean success = true;
3379                 synchronized (mInstallLock) {
3380                     try {
3381                         mInstaller.freeCache(volumeUuid, freeStorageSize);
3382                     } catch (InstallerException e) {
3383                         Slog.w(TAG, "Couldn't clear application caches: " + e);
3384                         success = false;
3385                     }
3386                 }
3387                 if (observer != null) {
3388                     try {
3389                         observer.onRemoveCompleted(null, success);
3390                     } catch (RemoteException e) {
3391                         Slog.w(TAG, "RemoveException when invoking call back");
3392                     }
3393                 }
3394             }
3395         });
3396     }
3397
3398     @Override
3399     public void freeStorage(final String volumeUuid, final long freeStorageSize,
3400             final IntentSender pi) {
3401         mContext.enforceCallingOrSelfPermission(
3402                 android.Manifest.permission.CLEAR_APP_CACHE, null);
3403         // Queue up an async operation since clearing cache may take a little while.
3404         mHandler.post(new Runnable() {
3405             public void run() {
3406                 mHandler.removeCallbacks(this);
3407                 boolean success = true;
3408                 synchronized (mInstallLock) {
3409                     try {
3410                         mInstaller.freeCache(volumeUuid, freeStorageSize);
3411                     } catch (InstallerException e) {
3412                         Slog.w(TAG, "Couldn't clear application caches: " + e);
3413                         success = false;
3414                     }
3415                 }
3416                 if(pi != null) {
3417                     try {
3418                         // Callback via pending intent
3419                         int code = success ? 1 : 0;
3420                         pi.sendIntent(null, code, null,
3421                                 null, null);
3422                     } catch (SendIntentException e1) {
3423                         Slog.i(TAG, "Failed to send pending intent");
3424                     }
3425                 }
3426             }
3427         });
3428     }
3429
3430     void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3431         synchronized (mInstallLock) {
3432             try {
3433                 mInstaller.freeCache(volumeUuid, freeStorageSize);
3434             } catch (InstallerException e) {
3435                 throw new IOException("Failed to free enough space", e);
3436             }
3437         }
3438     }
3439
3440     /**
3441      * Update given flags based on encryption status of current user.
3442      */
3443     private int updateFlags(int flags, int userId) {
3444         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3445                 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3446             // Caller expressed an explicit opinion about what encryption
3447             // aware/unaware components they want to see, so fall through and
3448             // give them what they want
3449         } else {
3450             // Caller expressed no opinion, so match based on user state
3451             if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3452                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3453             } else {
3454                 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3455             }
3456         }
3457         return flags;
3458     }
3459
3460     private UserManagerInternal getUserManagerInternal() {
3461         if (mUserManagerInternal == null) {
3462             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3463         }
3464         return mUserManagerInternal;
3465     }
3466
3467     /**
3468      * Update given flags when being used to request {@link PackageInfo}.
3469      */
3470     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3471         boolean triaged = true;
3472         if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3473                 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3474             // Caller is asking for component details, so they'd better be
3475             // asking for specific encryption matching behavior, or be triaged
3476             if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3477                     | PackageManager.MATCH_DIRECT_BOOT_AWARE
3478                     | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3479                 triaged = false;
3480             }
3481         }
3482         if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3483                 | PackageManager.MATCH_SYSTEM_ONLY
3484                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3485             triaged = false;
3486         }
3487         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3488             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3489                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3490         }
3491         return updateFlags(flags, userId);
3492     }
3493
3494     /**
3495      * Update given flags when being used to request {@link ApplicationInfo}.
3496      */
3497     private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3498         return updateFlagsForPackage(flags, userId, cookie);
3499     }
3500
3501     /**
3502      * Update given flags when being used to request {@link ComponentInfo}.
3503      */
3504     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3505         if (cookie instanceof Intent) {
3506             if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3507                 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3508             }
3509         }
3510
3511         boolean triaged = true;
3512         // Caller is asking for component details, so they'd better be
3513         // asking for specific encryption matching behavior, or be triaged
3514         if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3515                 | PackageManager.MATCH_DIRECT_BOOT_AWARE
3516                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3517             triaged = false;
3518         }
3519         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3520             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3521                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3522         }
3523
3524         return updateFlags(flags, userId);
3525     }
3526
3527     /**
3528      * Update given flags when being used to request {@link ResolveInfo}.
3529      */
3530     int updateFlagsForResolve(int flags, int userId, Object cookie) {
3531         // Safe mode means we shouldn't match any third-party components
3532         if (mSafeMode) {
3533             flags |= PackageManager.MATCH_SYSTEM_ONLY;
3534         }
3535
3536         return updateFlagsForComponent(flags, userId, cookie);
3537     }
3538
3539     @Override
3540     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3541         if (!sUserManager.exists(userId)) return null;
3542         flags = updateFlagsForComponent(flags, userId, component);
3543         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3544                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
3545         synchronized (mPackages) {
3546             PackageParser.Activity a = mActivities.mActivities.get(component);
3547
3548             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3549             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3550                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3551                 if (ps == null) return null;
3552                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3553                         userId);
3554             }
3555             if (mResolveComponentName.equals(component)) {
3556                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
3557                         new PackageUserState(), userId);
3558             }
3559         }
3560         return null;
3561     }
3562
3563     @Override
3564     public boolean activitySupportsIntent(ComponentName component, Intent intent,
3565             String resolvedType) {
3566         synchronized (mPackages) {
3567             if (component.equals(mResolveComponentName)) {
3568                 // The resolver supports EVERYTHING!
3569                 return true;
3570             }
3571             PackageParser.Activity a = mActivities.mActivities.get(component);
3572             if (a == null) {
3573                 return false;
3574             }
3575             for (int i=0; i<a.intents.size(); i++) {
3576                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3577                         intent.getData(), intent.getCategories(), TAG) >= 0) {
3578                     return true;
3579                 }
3580             }
3581             return false;
3582         }
3583     }
3584
3585     @Override
3586     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3587         if (!sUserManager.exists(userId)) return null;
3588         flags = updateFlagsForComponent(flags, userId, component);
3589         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3590                 false /* requireFullPermission */, false /* checkShell */, "get receiver info");
3591         synchronized (mPackages) {
3592             PackageParser.Activity a = mReceivers.mActivities.get(component);
3593             if (DEBUG_PACKAGE_INFO) Log.v(
3594                 TAG, "getReceiverInfo " + component + ": " + a);
3595             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3596                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3597                 if (ps == null) return null;
3598                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3599                         userId);
3600             }
3601         }
3602         return null;
3603     }
3604
3605     @Override
3606     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3607         if (!sUserManager.exists(userId)) return null;
3608         flags = updateFlagsForComponent(flags, userId, component);
3609         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3610                 false /* requireFullPermission */, false /* checkShell */, "get service info");
3611         synchronized (mPackages) {
3612             PackageParser.Service s = mServices.mServices.get(component);
3613             if (DEBUG_PACKAGE_INFO) Log.v(
3614                 TAG, "getServiceInfo " + component + ": " + s);
3615             if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3616                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3617                 if (ps == null) return null;
3618                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3619                         userId);
3620             }
3621         }
3622         return null;
3623     }
3624
3625     @Override
3626     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3627         if (!sUserManager.exists(userId)) return null;
3628         flags = updateFlagsForComponent(flags, userId, component);
3629         enforceCrossUserPermission(Binder.getCallingUid(), userId,
3630                 false /* requireFullPermission */, false /* checkShell */, "get provider info");
3631         synchronized (mPackages) {
3632             PackageParser.Provider p = mProviders.mProviders.get(component);
3633             if (DEBUG_PACKAGE_INFO) Log.v(
3634                 TAG, "getProviderInfo " + component + ": " + p);
3635             if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3636                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3637                 if (ps == null) return null;
3638                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3639                         userId);
3640             }
3641         }
3642         return null;
3643     }
3644
3645     @Override
3646     public String[] getSystemSharedLibraryNames() {
3647         Set<String> libSet;
3648         synchronized (mPackages) {
3649             libSet = mSharedLibraries.keySet();
3650             int size = libSet.size();
3651             if (size > 0) {
3652                 String[] libs = new String[size];
3653                 libSet.toArray(libs);
3654                 return libs;
3655             }
3656         }
3657         return null;
3658     }
3659
3660     @Override
3661     public @NonNull String getServicesSystemSharedLibraryPackageName() {
3662         synchronized (mPackages) {
3663             return mServicesSystemSharedLibraryPackageName;
3664         }
3665     }
3666
3667     @Override
3668     public @NonNull String getSharedSystemSharedLibraryPackageName() {
3669         synchronized (mPackages) {
3670             return mSharedSystemSharedLibraryPackageName;
3671         }
3672     }
3673
3674     @Override
3675     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
3676         synchronized (mPackages) {
3677             final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
3678
3679             final FeatureInfo fi = new FeatureInfo();
3680             fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3681                     FeatureInfo.GL_ES_VERSION_UNDEFINED);
3682             res.add(fi);
3683
3684             return new ParceledListSlice<>(res);
3685         }
3686     }
3687
3688     @Override
3689     public boolean hasSystemFeature(String name, int version) {
3690         synchronized (mPackages) {
3691             final FeatureInfo feat = mAvailableFeatures.get(name);
3692             if (feat == null) {
3693                 return false;
3694             } else {
3695                 return feat.version >= version;
3696             }
3697         }
3698     }
3699
3700     @Override
3701     public int checkPermission(String permName, String pkgName, int userId) {
3702         if (!sUserManager.exists(userId)) {
3703             return PackageManager.PERMISSION_DENIED;
3704         }
3705
3706         synchronized (mPackages) {
3707             final PackageParser.Package p = mPackages.get(pkgName);
3708             if (p != null && p.mExtras != null) {
3709                 final PackageSetting ps = (PackageSetting) p.mExtras;
3710                 final PermissionsState permissionsState = ps.getPermissionsState();
3711                 if (permissionsState.hasPermission(permName, userId)) {
3712                     return PackageManager.PERMISSION_GRANTED;
3713                 }
3714                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3715                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3716                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3717                     return PackageManager.PERMISSION_GRANTED;
3718                 }
3719             }
3720         }
3721
3722         return PackageManager.PERMISSION_DENIED;
3723     }
3724
3725     @Override
3726     public int checkUidPermission(String permName, int uid) {
3727         final int userId = UserHandle.getUserId(uid);
3728
3729         if (!sUserManager.exists(userId)) {
3730             return PackageManager.PERMISSION_DENIED;
3731         }
3732
3733         synchronized (mPackages) {
3734             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3735             if (obj != null) {
3736                 final SettingBase ps = (SettingBase) obj;
3737                 final PermissionsState permissionsState = ps.getPermissionsState();
3738                 if (permissionsState.hasPermission(permName, userId)) {
3739                     return PackageManager.PERMISSION_GRANTED;
3740                 }
3741                 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3742                 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3743                         .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3744                     return PackageManager.PERMISSION_GRANTED;
3745                 }
3746             } else {
3747                 ArraySet<String> perms = mSystemPermissions.get(uid);
3748                 if (perms != null) {
3749                     if (perms.contains(permName)) {
3750                         return PackageManager.PERMISSION_GRANTED;
3751                     }
3752                     if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3753                             .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3754                         return PackageManager.PERMISSION_GRANTED;
3755                     }
3756                 }
3757             }
3758         }
3759
3760         return PackageManager.PERMISSION_DENIED;
3761     }
3762
3763     @Override
3764     public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3765         if (UserHandle.getCallingUserId() != userId) {
3766             mContext.enforceCallingPermission(
3767                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3768                     "isPermissionRevokedByPolicy for user " + userId);
3769         }
3770
3771         if (checkPermission(permission, packageName, userId)
3772                 == PackageManager.PERMISSION_GRANTED) {
3773             return false;
3774         }
3775
3776         final long identity = Binder.clearCallingIdentity();
3777         try {
3778             final int flags = getPermissionFlags(permission, packageName, userId);
3779             return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3780         } finally {
3781             Binder.restoreCallingIdentity(identity);
3782         }
3783     }
3784
3785     @Override
3786     public String getPermissionControllerPackageName() {
3787         synchronized (mPackages) {
3788             return mRequiredInstallerPackage;
3789         }
3790     }
3791
3792     /**
3793      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3794      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3795      * @param checkShell whether to prevent shell from access if there's a debugging restriction
3796      * @param message the message to log on security exception
3797      */
3798     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3799             boolean checkShell, String message) {
3800         enforceCrossUserPermission(
3801               callingUid,
3802               userId,
3803               requireFullPermission,
3804               checkShell,
3805               false,
3806               message);
3807     }
3808
3809     private void enforceCrossUserPermission(int callingUid, int userId,
3810             boolean requireFullPermission, boolean checkShell,
3811             boolean requirePermissionWhenSameUser, String message) {
3812         if (userId < 0) {
3813             throw new IllegalArgumentException("Invalid userId " + userId);
3814         }
3815         if (checkShell) {
3816             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3817         }
3818         if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
3819         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3820             if (requireFullPermission) {
3821                 mContext.enforceCallingOrSelfPermission(
3822                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3823             } else {
3824                 try {
3825                     mContext.enforceCallingOrSelfPermission(
3826                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3827                 } catch (SecurityException se) {
3828                     mContext.enforceCallingOrSelfPermission(
3829                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3830                 }
3831             }
3832         }
3833     }
3834
3835     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3836         if (callingUid == Process.SHELL_UID) {
3837             if (userHandle >= 0
3838                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
3839                 throw new SecurityException("Shell does not have permission to access user "
3840                         + userHandle);
3841             } else if (userHandle < 0) {
3842                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3843                         + Debug.getCallers(3));
3844             }
3845         }
3846     }
3847
3848     private BasePermission findPermissionTreeLP(String permName) {
3849         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3850             if (permName.startsWith(bp.name) &&
3851                     permName.length() > bp.name.length() &&
3852                     permName.charAt(bp.name.length()) == '.') {
3853                 return bp;
3854             }
3855         }
3856         return null;
3857     }
3858
3859     private BasePermission checkPermissionTreeLP(String permName) {
3860         if (permName != null) {
3861             BasePermission bp = findPermissionTreeLP(permName);
3862             if (bp != null) {
3863                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3864                     return bp;
3865                 }
3866                 throw new SecurityException("Calling uid "
3867                         + Binder.getCallingUid()
3868                         + " is not allowed to add to permission tree "
3869                         + bp.name + " owned by uid " + bp.uid);
3870             }
3871         }
3872         throw new SecurityException("No permission tree found for " + permName);
3873     }
3874
3875     static boolean compareStrings(CharSequence s1, CharSequence s2) {
3876         if (s1 == null) {
3877             return s2 == null;
3878         }
3879         if (s2 == null) {
3880             return false;
3881         }
3882         if (s1.getClass() != s2.getClass()) {
3883             return false;
3884         }
3885         return s1.equals(s2);
3886     }
3887
3888     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3889         if (pi1.icon != pi2.icon) return false;
3890         if (pi1.logo != pi2.logo) return false;
3891         if (pi1.protectionLevel != pi2.protectionLevel) return false;
3892         if (!compareStrings(pi1.name, pi2.name)) return false;
3893         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3894         // We'll take care of setting this one.
3895         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3896         // These are not currently stored in settings.
3897         //if (!compareStrings(pi1.group, pi2.group)) return false;
3898         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3899         //if (pi1.labelRes != pi2.labelRes) return false;
3900         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3901         return true;
3902     }
3903
3904     int permissionInfoFootprint(PermissionInfo info) {
3905         int size = info.name.length();
3906         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3907         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3908         return size;
3909     }
3910
3911     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3912         int size = 0;
3913         for (BasePermission perm : mSettings.mPermissions.values()) {
3914             if (perm.uid == tree.uid) {
3915                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3916             }
3917         }
3918         return size;
3919     }
3920
3921     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3922         // We calculate the max size of permissions defined by this uid and throw
3923         // if that plus the size of 'info' would exceed our stated maximum.
3924         if (tree.uid != Process.SYSTEM_UID) {
3925             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3926             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3927                 throw new SecurityException("Permission tree size cap exceeded");
3928             }
3929         }
3930     }
3931
3932     boolean addPermissionLocked(PermissionInfo info, boolean async) {
3933         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3934             throw new SecurityException("Label must be specified in permission");
3935         }
3936         BasePermission tree = checkPermissionTreeLP(info.name);
3937         BasePermission bp = mSettings.mPermissions.get(info.name);
3938         boolean added = bp == null;
3939         boolean changed = true;
3940         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3941         if (added) {
3942             enforcePermissionCapLocked(info, tree);
3943             bp = new BasePermission(info.name, tree.sourcePackage,
3944                     BasePermission.TYPE_DYNAMIC);
3945         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3946             throw new SecurityException(
3947                     "Not allowed to modify non-dynamic permission "
3948                     + info.name);
3949         } else {
3950             if (bp.protectionLevel == fixedLevel
3951                     && bp.perm.owner.equals(tree.perm.owner)
3952                     && bp.uid == tree.uid
3953                     && comparePermissionInfos(bp.perm.info, info)) {
3954                 changed = false;
3955             }
3956         }
3957         bp.protectionLevel = fixedLevel;
3958         info = new PermissionInfo(info);
3959         info.protectionLevel = fixedLevel;
3960         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3961         bp.perm.info.packageName = tree.perm.info.packageName;
3962         bp.uid = tree.uid;
3963         if (added) {
3964             mSettings.mPermissions.put(info.name, bp);
3965         }
3966         if (changed) {
3967             if (!async) {
3968                 mSettings.writeLPr();
3969             } else {
3970                 scheduleWriteSettingsLocked();
3971             }
3972         }
3973         return added;
3974     }
3975
3976     @Override
3977     public boolean addPermission(PermissionInfo info) {
3978         synchronized (mPackages) {
3979             return addPermissionLocked(info, false);
3980         }
3981     }
3982
3983     @Override
3984     public boolean addPermissionAsync(PermissionInfo info) {
3985         synchronized (mPackages) {
3986             return addPermissionLocked(info, true);
3987         }
3988     }
3989
3990     @Override
3991     public void removePermission(String name) {
3992         synchronized (mPackages) {
3993             checkPermissionTreeLP(name);
3994             BasePermission bp = mSettings.mPermissions.get(name);
3995             if (bp != null) {
3996                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
3997                     throw new SecurityException(
3998                             "Not allowed to modify non-dynamic permission "
3999                             + name);
4000                 }
4001                 mSettings.mPermissions.remove(name);
4002                 mSettings.writeLPr();
4003             }
4004         }
4005     }
4006
4007     private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4008             BasePermission bp) {
4009         int index = pkg.requestedPermissions.indexOf(bp.name);
4010         if (index == -1) {
4011             throw new SecurityException("Package " + pkg.packageName
4012                     + " has not requested permission " + bp.name);
4013         }
4014         if (!bp.isRuntime() && !bp.isDevelopment()) {
4015             throw new SecurityException("Permission " + bp.name
4016                     + " is not a changeable permission type");
4017         }
4018     }
4019
4020     @Override
4021     public void grantRuntimePermission(String packageName, String name, final int userId) {
4022         if (!sUserManager.exists(userId)) {
4023             Log.e(TAG, "No such user:" + userId);
4024             return;
4025         }
4026
4027         mContext.enforceCallingOrSelfPermission(
4028                 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4029                 "grantRuntimePermission");
4030
4031         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4032                 true /* requireFullPermission */, true /* checkShell */,
4033                 "grantRuntimePermission");
4034
4035         final int uid;
4036         final SettingBase sb;
4037
4038         synchronized (mPackages) {
4039             final PackageParser.Package pkg = mPackages.get(packageName);
4040             if (pkg == null) {
4041                 throw new IllegalArgumentException("Unknown package: " + packageName);
4042             }
4043
4044             final BasePermission bp = mSettings.mPermissions.get(name);
4045             if (bp == null) {
4046                 throw new IllegalArgumentException("Unknown permission: " + name);
4047             }
4048
4049             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4050
4051             // If a permission review is required for legacy apps we represent
4052             // their permissions as always granted runtime ones since we need
4053             // to keep the review required permission flag per user while an
4054             // install permission's state is shared across all users.
4055             if (Build.PERMISSIONS_REVIEW_REQUIRED
4056                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4057                     && bp.isRuntime()) {
4058                 return;
4059             }
4060
4061             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4062             sb = (SettingBase) pkg.mExtras;
4063             if (sb == null) {
4064                 throw new IllegalArgumentException("Unknown package: " + packageName);
4065             }
4066
4067             final PermissionsState permissionsState = sb.getPermissionsState();
4068
4069             final int flags = permissionsState.getPermissionFlags(name, userId);
4070             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4071                 throw new SecurityException("Cannot grant system fixed permission "
4072                         + name + " for package " + packageName);
4073             }
4074
4075             if (bp.isDevelopment()) {
4076                 // Development permissions must be handled specially, since they are not
4077                 // normal runtime permissions.  For now they apply to all users.
4078                 if (permissionsState.grantInstallPermission(bp) !=
4079                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4080                     scheduleWriteSettingsLocked();
4081                 }
4082                 return;
4083             }
4084
4085             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4086                 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4087                 return;
4088             }
4089
4090             final int result = permissionsState.grantRuntimePermission(bp, userId);
4091             switch (result) {
4092                 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4093                     return;
4094                 }
4095
4096                 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4097                     final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4098                     mHandler.post(new Runnable() {
4099                         @Override
4100                         public void run() {
4101                             killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4102                         }
4103                     });
4104                 }
4105                 break;
4106             }
4107
4108             mOnPermissionChangeListeners.onPermissionsChanged(uid);
4109
4110             // Not critical if that is lost - app has to request again.
4111             mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4112         }
4113
4114         // Only need to do this if user is initialized. Otherwise it's a new user
4115         // and there are no processes running as the user yet and there's no need
4116         // to make an expensive call to remount processes for the changed permissions.
4117         if (READ_EXTERNAL_STORAGE.equals(name)
4118                 || WRITE_EXTERNAL_STORAGE.equals(name)) {
4119             final long token = Binder.clearCallingIdentity();
4120             try {
4121                 if (sUserManager.isInitialized(userId)) {
4122                     MountServiceInternal mountServiceInternal = LocalServices.getService(
4123                             MountServiceInternal.class);
4124                     mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
4125                 }
4126             } finally {
4127                 Binder.restoreCallingIdentity(token);
4128             }
4129         }
4130     }
4131
4132     @Override
4133     public void revokeRuntimePermission(String packageName, String name, int userId) {
4134         if (!sUserManager.exists(userId)) {
4135             Log.e(TAG, "No such user:" + userId);
4136             return;
4137         }
4138
4139         mContext.enforceCallingOrSelfPermission(
4140                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4141                 "revokeRuntimePermission");
4142
4143         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4144                 true /* requireFullPermission */, true /* checkShell */,
4145                 "revokeRuntimePermission");
4146
4147         final int appId;
4148
4149         synchronized (mPackages) {
4150             final PackageParser.Package pkg = mPackages.get(packageName);
4151             if (pkg == null) {
4152                 throw new IllegalArgumentException("Unknown package: " + packageName);
4153             }
4154
4155             final BasePermission bp = mSettings.mPermissions.get(name);
4156             if (bp == null) {
4157                 throw new IllegalArgumentException("Unknown permission: " + name);
4158             }
4159
4160             enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4161
4162             // If a permission review is required for legacy apps we represent
4163             // their permissions as always granted runtime ones since we need
4164             // to keep the review required permission flag per user while an
4165             // install permission's state is shared across all users.
4166             if (Build.PERMISSIONS_REVIEW_REQUIRED
4167                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4168                     && bp.isRuntime()) {
4169                 return;
4170             }
4171
4172             SettingBase sb = (SettingBase) pkg.mExtras;
4173             if (sb == null) {
4174                 throw new IllegalArgumentException("Unknown package: " + packageName);
4175             }
4176
4177             final PermissionsState permissionsState = sb.getPermissionsState();
4178
4179             final int flags = permissionsState.getPermissionFlags(name, userId);
4180             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4181                 throw new SecurityException("Cannot revoke system fixed permission "
4182                         + name + " for package " + packageName);
4183             }
4184
4185             if (bp.isDevelopment()) {
4186                 // Development permissions must be handled specially, since they are not
4187                 // normal runtime permissions.  For now they apply to all users.
4188                 if (permissionsState.revokeInstallPermission(bp) !=
4189                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
4190                     scheduleWriteSettingsLocked();
4191                 }
4192                 return;
4193             }
4194
4195             if (permissionsState.revokeRuntimePermission(bp, userId) ==
4196                     PermissionsState.PERMISSION_OPERATION_FAILURE) {
4197                 return;
4198             }
4199
4200             mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4201
4202             // Critical, after this call app should never have the permission.
4203             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4204
4205             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4206         }
4207
4208         killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4209     }
4210
4211     /**
4212      * We might auto-grant permissions if any permission of the group is already granted. Hence if
4213      * the group of a granted permission changes we need to revoke it to avoid having permissions of
4214      * the new group auto-granted.
4215      *
4216      * @param newPackage The new package that was installed
4217      * @param oldPackage The old package that was updated
4218      * @param allPackageNames All package names
4219      */
4220     private void revokeRuntimePermissionsIfGroupChanged(
4221             PackageParser.Package newPackage,
4222             PackageParser.Package oldPackage,
4223             ArrayList<String> allPackageNames) {
4224         final int numOldPackagePermissions = oldPackage.permissions.size();
4225         final ArrayMap<String, String> oldPermissionNameToGroupName
4226                 = new ArrayMap<>(numOldPackagePermissions);
4227
4228         for (int i = 0; i < numOldPackagePermissions; i++) {
4229             final PackageParser.Permission permission = oldPackage.permissions.get(i);
4230
4231             if (permission.group != null) {
4232                 oldPermissionNameToGroupName.put(permission.info.name,
4233                         permission.group.info.name);
4234             }
4235         }
4236
4237         final int numNewPackagePermissions = newPackage.permissions.size();
4238         for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
4239                 newPermissionNum++) {
4240             final PackageParser.Permission newPermission =
4241                     newPackage.permissions.get(newPermissionNum);
4242             final int newProtection = newPermission.info.protectionLevel;
4243
4244             if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
4245                 final String permissionName = newPermission.info.name;
4246                 final String newPermissionGroupName =
4247                         newPermission.group == null ? null : newPermission.group.info.name;
4248                 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
4249                         permissionName);
4250
4251                 if (newPermissionGroupName != null
4252                         && !newPermissionGroupName.equals(oldPermissionGroupName)) {
4253                     final List<UserInfo> users = mContext.getSystemService(UserManager.class)
4254                             .getUsers();
4255
4256                     final int numUsers = users.size();
4257                     for (int userNum = 0; userNum < numUsers; userNum++) {
4258                         final int userId = users.get(userNum).id;
4259                         final int numPackages = allPackageNames.size();
4260                         for (int packageNum = 0; packageNum < numPackages; packageNum++) {
4261                             final String packageName = allPackageNames.get(packageNum);
4262
4263                             if (checkPermission(permissionName, packageName, userId)
4264                                     == PackageManager.PERMISSION_GRANTED) {
4265                                 EventLog.writeEvent(0x534e4554, "72710897",
4266                                         newPackage.applicationInfo.uid,
4267                                         "Revoking permission", permissionName, "from package",
4268                                         packageName, "as the group changed from",
4269                                         oldPermissionGroupName, "to", newPermissionGroupName);
4270
4271                                 try {
4272                                     revokeRuntimePermission(packageName, permissionName, userId);
4273                                 } catch (IllegalArgumentException e) {
4274                                     Slog.e(TAG, "Could not revoke " + permissionName + " from "
4275                                             + packageName, e);
4276                                 }
4277                             }
4278                         }
4279                     }
4280                 }
4281             }
4282         }
4283     }
4284
4285
4286     @Override
4287     public void resetRuntimePermissions() {
4288         mContext.enforceCallingOrSelfPermission(
4289                 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4290                 "revokeRuntimePermission");
4291
4292         int callingUid = Binder.getCallingUid();
4293         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4294             mContext.enforceCallingOrSelfPermission(
4295                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4296                     "resetRuntimePermissions");
4297         }
4298
4299         synchronized (mPackages) {
4300             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
4301             for (int userId : UserManagerService.getInstance().getUserIds()) {
4302                 final int packageCount = mPackages.size();
4303                 for (int i = 0; i < packageCount; i++) {
4304                     PackageParser.Package pkg = mPackages.valueAt(i);
4305                     if (!(pkg.mExtras instanceof PackageSetting)) {
4306                         continue;
4307                     }
4308                     PackageSetting ps = (PackageSetting) pkg.mExtras;
4309                     resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
4310                 }
4311             }
4312         }
4313     }
4314
4315     @Override
4316     public int getPermissionFlags(String name, String packageName, int userId) {
4317         if (!sUserManager.exists(userId)) {
4318             return 0;
4319         }
4320
4321         enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
4322
4323         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4324                 true /* requireFullPermission */, false /* checkShell */,
4325                 "getPermissionFlags");
4326
4327         synchronized (mPackages) {
4328             final PackageParser.Package pkg = mPackages.get(packageName);
4329             if (pkg == null) {
4330                 return 0;
4331             }
4332
4333             final BasePermission bp = mSettings.mPermissions.get(name);
4334             if (bp == null) {
4335                 return 0;
4336             }
4337
4338             SettingBase sb = (SettingBase) pkg.mExtras;
4339             if (sb == null) {
4340                 return 0;
4341             }
4342
4343             PermissionsState permissionsState = sb.getPermissionsState();
4344             return permissionsState.getPermissionFlags(name, userId);
4345         }
4346     }
4347
4348     @Override
4349     public void updatePermissionFlags(String name, String packageName, int flagMask,
4350             int flagValues, int userId) {
4351         if (!sUserManager.exists(userId)) {
4352             return;
4353         }
4354
4355         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
4356
4357         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4358                 true /* requireFullPermission */, true /* checkShell */,
4359                 "updatePermissionFlags");
4360
4361         // Only the system can change these flags and nothing else.
4362         if (getCallingUid() != Process.SYSTEM_UID) {
4363             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4364             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4365             flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4366             flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4367             flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
4368         }
4369
4370         synchronized (mPackages) {
4371             final PackageParser.Package pkg = mPackages.get(packageName);
4372             if (pkg == null) {
4373                 throw new IllegalArgumentException("Unknown package: " + packageName);
4374             }
4375
4376             final BasePermission bp = mSettings.mPermissions.get(name);
4377             if (bp == null) {
4378                 throw new IllegalArgumentException("Unknown permission: " + name);
4379             }
4380
4381             SettingBase sb = (SettingBase) pkg.mExtras;
4382             if (sb == null) {
4383                 throw new IllegalArgumentException("Unknown package: " + packageName);
4384             }
4385
4386             PermissionsState permissionsState = sb.getPermissionsState();
4387
4388             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
4389
4390             if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
4391                 // Install and runtime permissions are stored in different places,
4392                 // so figure out what permission changed and persist the change.
4393                 if (permissionsState.getInstallPermissionState(name) != null) {
4394                     scheduleWriteSettingsLocked();
4395                 } else if (permissionsState.getRuntimePermissionState(name, userId) != null
4396                         || hadState) {
4397                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4398                 }
4399             }
4400         }
4401     }
4402
4403     /**
4404      * Update the permission flags for all packages and runtime permissions of a user in order
4405      * to allow device or profile owner to remove POLICY_FIXED.
4406      */
4407     @Override
4408     public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
4409         if (!sUserManager.exists(userId)) {
4410             return;
4411         }
4412
4413         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
4414
4415         enforceCrossUserPermission(Binder.getCallingUid(), userId,
4416                 true /* requireFullPermission */, true /* checkShell */,
4417                 "updatePermissionFlagsForAllApps");
4418
4419         // Only the system can change system fixed flags.
4420         if (getCallingUid() != Process.SYSTEM_UID) {
4421             flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4422             flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4423         }
4424
4425         synchronized (mPackages) {
4426             boolean changed = false;
4427             final int packageCount = mPackages.size();
4428             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4429                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4430                 SettingBase sb = (SettingBase) pkg.mExtras;
4431                 if (sb == null) {
4432                     continue;
4433                 }
4434                 PermissionsState permissionsState = sb.getPermissionsState();
4435                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4436                         userId, flagMask, flagValues);
4437             }
4438             if (changed) {
4439                 mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4440             }
4441         }
4442     }
4443
4444     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4445         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4446                 != PackageManager.PERMISSION_GRANTED
4447             && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4448                 != PackageManager.PERMISSION_GRANTED) {
4449             throw new SecurityException(message + " requires "
4450                     + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4451                     + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4452         }
4453     }
4454
4455     @Override
4456     public boolean shouldShowRequestPermissionRationale(String permissionName,
4457             String packageName, int userId) {
4458         if (UserHandle.getCallingUserId() != userId) {
4459             mContext.enforceCallingPermission(
4460                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4461                     "canShowRequestPermissionRationale for user " + userId);
4462         }
4463
4464         final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
4465         if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4466             return false;
4467         }
4468
4469         if (checkPermission(permissionName, packageName, userId)
4470                 == PackageManager.PERMISSION_GRANTED) {
4471             return false;
4472         }
4473
4474         final int flags;
4475
4476         final long identity = Binder.clearCallingIdentity();
4477         try {
4478             flags = getPermissionFlags(permissionName,
4479                     packageName, userId);
4480         } finally {
4481             Binder.restoreCallingIdentity(identity);
4482         }
4483
4484         final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4485                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4486                 | PackageManager.FLAG_PERMISSION_USER_FIXED;
4487
4488         if ((flags & fixedFlags) != 0) {
4489             return false;
4490         }
4491
4492         return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4493     }
4494
4495     @Override
4496     public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4497         mContext.enforceCallingOrSelfPermission(
4498                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4499                 "addOnPermissionsChangeListener");
4500
4501         synchronized (mPackages) {
4502             mOnPermissionChangeListeners.addListenerLocked(listener);
4503         }
4504     }
4505
4506     @Override
4507     public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4508         synchronized (mPackages) {
4509             mOnPermissionChangeListeners.removeListenerLocked(listener);
4510         }
4511     }
4512
4513     @Override
4514     public boolean isProtectedBroadcast(String actionName) {
4515         synchronized (mPackages) {
4516             if (mProtectedBroadcasts.contains(actionName)) {
4517                 return true;
4518             } else if (actionName != null) {
4519                 // TODO: remove these terrible hacks
4520                 if (actionName.startsWith("android.net.netmon.lingerExpired")
4521                         || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
4522                         || actionName.startsWith("com.android.internal.telephony.data-reconnect")
4523                         || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
4524                     return true;
4525                 }
4526             }
4527         }
4528         return false;
4529     }
4530
4531     @Override
4532     public int checkSignatures(String pkg1, String pkg2) {
4533         synchronized (mPackages) {
4534             final PackageParser.Package p1 = mPackages.get(pkg1);
4535             final PackageParser.Package p2 = mPackages.get(pkg2);
4536             if (p1 == null || p1.mExtras == null
4537                     || p2 == null || p2.mExtras == null) {
4538                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4539             }
4540             return compareSignatures(p1.mSignatures, p2.mSignatures);
4541         }
4542     }
4543
4544     @Override
4545     public int checkUidSignatures(int uid1, int uid2) {
4546         // Map to base uids.
4547         uid1 = UserHandle.getAppId(uid1);
4548         uid2 = UserHandle.getAppId(uid2);
4549         // reader
4550         synchronized (mPackages) {
4551             Signature[] s1;
4552             Signature[] s2;
4553             Object obj = mSettings.getUserIdLPr(uid1);
4554             if (obj != null) {
4555                 if (obj instanceof SharedUserSetting) {
4556                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4557                 } else if (obj instanceof PackageSetting) {
4558                     s1 = ((PackageSetting)obj).signatures.mSignatures;
4559                 } else {
4560                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4561                 }
4562             } else {
4563                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4564             }
4565             obj = mSettings.getUserIdLPr(uid2);
4566             if (obj != null) {
4567                 if (obj instanceof SharedUserSetting) {
4568                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4569                 } else if (obj instanceof PackageSetting) {
4570                     s2 = ((PackageSetting)obj).signatures.mSignatures;
4571                 } else {
4572                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4573                 }
4574             } else {
4575                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4576             }
4577             return compareSignatures(s1, s2);
4578         }
4579     }
4580
4581     /**
4582      * This method should typically only be used when granting or revoking
4583      * permissions, since the app may immediately restart after this call.
4584      * <p>
4585      * If you're doing surgery on app code/data, use {@link PackageFreezer} to
4586      * guard your work against the app being relaunched.
4587      */
4588     private void killUid(int appId, int userId, String reason) {
4589         final long identity = Binder.clearCallingIdentity();
4590         try {
4591             IActivityManager am = ActivityManagerNative.getDefault();
4592             if (am != null) {
4593                 try {
4594                     am.killUid(appId, userId, reason);
4595                 } catch (RemoteException e) {
4596                     /* ignore - same process */
4597                 }
4598             }
4599         } finally {
4600             Binder.restoreCallingIdentity(identity);
4601         }
4602     }
4603
4604     /**
4605      * Compares two sets of signatures. Returns:
4606      * <br />
4607      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4608      * <br />
4609      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4610      * <br />
4611      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4612      * <br />
4613      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4614      * <br />
4615      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4616      */
4617     static int compareSignatures(Signature[] s1, Signature[] s2) {
4618         if (s1 == null) {
4619             return s2 == null
4620                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
4621                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4622         }
4623
4624         if (s2 == null) {
4625             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4626         }
4627
4628         if (s1.length != s2.length) {
4629             return PackageManager.SIGNATURE_NO_MATCH;
4630         }
4631
4632         // Since both signature sets are of size 1, we can compare without HashSets.
4633         if (s1.length == 1) {
4634             return s1[0].equals(s2[0]) ?
4635                     PackageManager.SIGNATURE_MATCH :
4636                     PackageManager.SIGNATURE_NO_MATCH;
4637         }
4638
4639         ArraySet<Signature> set1 = new ArraySet<Signature>();
4640         for (Signature sig : s1) {
4641             set1.add(sig);
4642         }
4643         ArraySet<Signature> set2 = new ArraySet<Signature>();
4644         for (Signature sig : s2) {
4645             set2.add(sig);
4646         }
4647         // Make sure s2 contains all signatures in s1.
4648         if (set1.equals(set2)) {
4649             return PackageManager.SIGNATURE_MATCH;
4650         }
4651         return PackageManager.SIGNATURE_NO_MATCH;
4652     }
4653
4654     /**
4655      * If the database version for this type of package (internal storage or
4656      * external storage) is less than the version where package signatures
4657      * were updated, return true.
4658      */
4659     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4660         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4661         return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4662     }
4663
4664     /**
4665      * Used for backward compatibility to make sure any packages with
4666      * certificate chains get upgraded to the new style. {@code existingSigs}
4667      * will be in the old format (since they were stored on disk from before the
4668      * system upgrade) and {@code scannedSigs} will be in the newer format.
4669      */
4670     private int compareSignaturesCompat(PackageSignatures existingSigs,
4671             PackageParser.Package scannedPkg) {
4672         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4673             return PackageManager.SIGNATURE_NO_MATCH;
4674         }
4675
4676         ArraySet<Signature> existingSet = new ArraySet<Signature>();
4677         for (Signature sig : existingSigs.mSignatures) {
4678             existingSet.add(sig);
4679         }
4680         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4681         for (Signature sig : scannedPkg.mSignatures) {
4682             try {
4683                 Signature[] chainSignatures = sig.getChainSignatures();
4684                 for (Signature chainSig : chainSignatures) {
4685                     scannedCompatSet.add(chainSig);
4686                 }
4687             } catch (CertificateEncodingException e) {
4688                 scannedCompatSet.add(sig);
4689             }
4690         }
4691         /*
4692          * Make sure the expanded scanned set contains all signatures in the
4693          * existing one.
4694          */
4695         if (scannedCompatSet.equals(existingSet)) {
4696             // Migrate the old signatures to the new scheme.
4697             existingSigs.assignSignatures(scannedPkg.mSignatures);
4698             // The new KeySets will be re-added later in the scanning process.
4699             synchronized (mPackages) {
4700                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4701             }
4702             return PackageManager.SIGNATURE_MATCH;
4703         }
4704         return PackageManager.SIGNATURE_NO_MATCH;
4705     }
4706
4707     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4708         final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4709         return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4710     }
4711
4712     private int compareSignaturesRecover(PackageSignatures existingSigs,
4713             PackageParser.Package scannedPkg) {
4714         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4715             return PackageManager.SIGNATURE_NO_MATCH;
4716         }
4717
4718         String msg = null;
4719         try {
4720             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4721                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4722                         + scannedPkg.packageName);
4723                 return PackageManager.SIGNATURE_MATCH;
4724             }
4725         } catch (CertificateException e) {
4726             msg = e.getMessage();
4727         }
4728
4729         logCriticalInfo(Log.INFO,
4730                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4731         return PackageManager.SIGNATURE_NO_MATCH;
4732     }
4733
4734     @Override
4735     public List<String> getAllPackages() {
4736         synchronized (mPackages) {
4737             return new ArrayList<String>(mPackages.keySet());
4738         }
4739     }
4740
4741     @Override
4742     public String[] getPackagesForUid(int uid) {
4743         uid = UserHandle.getAppId(uid);
4744         // reader
4745         synchronized (mPackages) {
4746             Object obj = mSettings.getUserIdLPr(uid);
4747             if (obj instanceof SharedUserSetting) {
4748                 final SharedUserSetting sus = (SharedUserSetting) obj;
4749                 final int N = sus.packages.size();
4750                 final String[] res = new String[N];
4751                 for (int i = 0; i < N; i++) {
4752                     res[i] = sus.packages.valueAt(i).name;
4753                 }
4754                 return res;
4755             } else if (obj instanceof PackageSetting) {
4756                 final PackageSetting ps = (PackageSetting) obj;
4757                 return new String[] { ps.name };
4758             }
4759         }
4760         return null;
4761     }
4762
4763     @Override
4764     public String getNameForUid(int uid) {
4765         // reader
4766         synchronized (mPackages) {
4767             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4768             if (obj instanceof SharedUserSetting) {
4769                 final SharedUserSetting sus = (SharedUserSetting) obj;
4770                 return sus.name + ":" + sus.userId;
4771             } else if (obj instanceof PackageSetting) {
4772                 final PackageSetting ps = (PackageSetting) obj;
4773                 return ps.name;
4774             }
4775         }
4776         return null;
4777     }
4778
4779     @Override
4780     public int getUidForSharedUser(String sharedUserName) {
4781         if(sharedUserName == null) {
4782             return -1;
4783         }
4784         // reader
4785         synchronized (mPackages) {
4786             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4787             if (suid == null) {
4788                 return -1;
4789             }
4790             return suid.userId;
4791         }
4792     }
4793
4794     @Override
4795     public int getFlagsForUid(int uid) {
4796         synchronized (mPackages) {
4797             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4798             if (obj instanceof SharedUserSetting) {
4799                 final SharedUserSetting sus = (SharedUserSetting) obj;
4800                 return sus.pkgFlags;
4801             } else if (obj instanceof PackageSetting) {
4802                 final PackageSetting ps = (PackageSetting) obj;
4803                 return ps.pkgFlags;
4804             }
4805         }
4806         return 0;
4807     }
4808
4809     @Override
4810     public int getPrivateFlagsForUid(int uid) {
4811         synchronized (mPackages) {
4812             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4813             if (obj instanceof SharedUserSetting) {
4814                 final SharedUserSetting sus = (SharedUserSetting) obj;
4815                 return sus.pkgPrivateFlags;
4816             } else if (obj instanceof PackageSetting) {
4817                 final PackageSetting ps = (PackageSetting) obj;
4818                 return ps.pkgPrivateFlags;
4819             }
4820         }
4821         return 0;
4822     }
4823
4824     @Override
4825     public boolean isUidPrivileged(int uid) {
4826         uid = UserHandle.getAppId(uid);
4827         // reader
4828         synchronized (mPackages) {
4829             Object obj = mSettings.getUserIdLPr(uid);
4830             if (obj instanceof SharedUserSetting) {
4831                 final SharedUserSetting sus = (SharedUserSetting) obj;
4832                 final Iterator<PackageSetting> it = sus.packages.iterator();
4833                 while (it.hasNext()) {
4834                     if (it.next().isPrivileged()) {
4835                         return true;
4836                     }
4837                 }
4838             } else if (obj instanceof PackageSetting) {
4839                 final PackageSetting ps = (PackageSetting) obj;
4840                 return ps.isPrivileged();
4841             }
4842         }
4843         return false;
4844     }
4845
4846     @Override
4847     public String[] getAppOpPermissionPackages(String permissionName) {
4848         synchronized (mPackages) {
4849             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4850             if (pkgs == null) {
4851                 return null;
4852             }
4853             return pkgs.toArray(new String[pkgs.size()]);
4854         }
4855     }
4856
4857     @Override
4858     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4859             int flags, int userId) {
4860         try {
4861             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
4862
4863             if (!sUserManager.exists(userId)) return null;
4864             flags = updateFlagsForResolve(flags, userId, intent);
4865             enforceCrossUserPermission(Binder.getCallingUid(), userId,
4866                     false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
4867
4868             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
4869             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
4870                     flags, userId);
4871             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4872
4873             final ResolveInfo bestChoice =
4874                     chooseBestActivity(intent, resolvedType, flags, query, userId);
4875             return bestChoice;
4876         } finally {
4877             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4878         }
4879     }
4880
4881     @Override
4882     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4883             IntentFilter filter, int match, ComponentName activity) {
4884         final int userId = UserHandle.getCallingUserId();
4885         if (DEBUG_PREFERRED) {
4886             Log.v(TAG, "setLastChosenActivity intent=" + intent
4887                 + " resolvedType=" + resolvedType
4888                 + " flags=" + flags
4889                 + " filter=" + filter
4890                 + " match=" + match
4891                 + " activity=" + activity);
4892             filter.dump(new PrintStreamPrinter(System.out), "    ");
4893         }
4894         intent.setComponent(null);
4895         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4896                 userId);
4897         // Find any earlier preferred or last chosen entries and nuke them
4898         findPreferredActivity(intent, resolvedType,
4899                 flags, query, 0, false, true, false, userId);
4900         // Add the new activity as the last chosen for this filter
4901         addPreferredActivityInternal(filter, match, null, activity, false, userId,
4902                 "Setting last chosen");
4903     }
4904
4905     @Override
4906     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4907         final int userId = UserHandle.getCallingUserId();
4908         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4909         final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4910                 userId);
4911         return findPreferredActivity(intent, resolvedType, flags, query, 0,
4912                 false, false, false, userId);
4913     }
4914
4915     private boolean isEphemeralDisabled() {
4916         // ephemeral apps have been disabled across the board
4917         if (DISABLE_EPHEMERAL_APPS) {
4918             return true;
4919         }
4920         // system isn't up yet; can't read settings, so, assume no ephemeral apps
4921         if (!mSystemReady) {
4922             return true;
4923         }
4924         // we can't get a content resolver until the system is ready; these checks must happen last
4925         final ContentResolver resolver = mContext.getContentResolver();
4926         if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) {
4927             return true;
4928         }
4929         return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0;
4930     }
4931
4932     private boolean isEphemeralAllowed(
4933             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
4934             boolean skipPackageCheck) {
4935         // Short circuit and return early if possible.
4936         if (isEphemeralDisabled()) {
4937             return false;
4938         }
4939         final int callingUser = UserHandle.getCallingUserId();
4940         if (callingUser != UserHandle.USER_SYSTEM) {
4941             return false;
4942         }
4943         if (mEphemeralResolverConnection == null) {
4944             return false;
4945         }
4946         if (intent.getComponent() != null) {
4947             return false;
4948         }
4949         if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
4950             return false;
4951         }
4952         if (!skipPackageCheck && intent.getPackage() != null) {
4953             return false;
4954         }
4955         final boolean isWebUri = hasWebURI(intent);
4956         if (!isWebUri || intent.getData().getHost() == null) {
4957             return false;
4958         }
4959         // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4960         synchronized (mPackages) {
4961             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
4962             for (int n = 0; n < count; n++) {
4963                 ResolveInfo info = resolvedActivities.get(n);
4964                 String packageName = info.activityInfo.packageName;
4965                 PackageSetting ps = mSettings.mPackages.get(packageName);
4966                 if (ps != null) {
4967                     // Try to get the status from User settings first
4968                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4969                     int status = (int) (packedStatus >> 32);
4970                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
4971                             || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4972                         if (DEBUG_EPHEMERAL) {
4973                             Slog.v(TAG, "DENY ephemeral apps;"
4974                                 + " pkg: " + packageName + ", status: " + status);
4975                         }
4976                         return false;
4977                     }
4978                 }
4979             }
4980         }
4981         // We've exhausted all ways to deny ephemeral application; let the system look for them.
4982         return true;
4983     }
4984
4985     private static EphemeralResolveInfo getEphemeralResolveInfo(
4986             Context context, EphemeralResolverConnection resolverConnection, Intent intent,
4987             String resolvedType, int userId, String packageName) {
4988         final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(),
4989                 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK);
4990         final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(),
4991                 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT);
4992         final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask,
4993                 ephemeralPrefixCount);
4994         final int[] shaPrefix = digest.getDigestPrefix();
4995         final byte[][] digestBytes = digest.getDigestBytes();
4996         final List<EphemeralResolveInfo> ephemeralResolveInfoList =
4997                 resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask);
4998         if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
4999             // No hash prefix match; there are no ephemeral apps for this domain.
5000             return null;
5001         }
5002
5003         // Go in reverse order so we match the narrowest scope first.
5004         for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
5005             for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
5006                 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
5007                     continue;
5008                 }
5009                 final List<IntentFilter> filters = ephemeralApplication.getFilters();
5010                 // No filters; this should never happen.
5011                 if (filters.isEmpty()) {
5012                     continue;
5013                 }
5014                 if (packageName != null
5015                         && !packageName.equals(ephemeralApplication.getPackageName())) {
5016                     continue;
5017                 }
5018                 // We have a domain match; resolve the filters to see if anything matches.
5019                 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
5020                 for (int j = filters.size() - 1; j >= 0; --j) {
5021                     final EphemeralResolveIntentInfo intentInfo =
5022                             new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
5023                     ephemeralResolver.addFilter(intentInfo);
5024                 }
5025                 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
5026                         intent, resolvedType, false /*defaultOnly*/, userId);
5027                 if (!matchedResolveInfoList.isEmpty()) {
5028                     return matchedResolveInfoList.get(0);
5029                 }
5030             }
5031         }
5032         // Hash or filter mis-match; no ephemeral apps for this domain.
5033         return null;
5034     }
5035
5036     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5037             int flags, List<ResolveInfo> query, int userId) {
5038         if (query != null) {
5039             final int N = query.size();
5040             if (N == 1) {
5041                 return query.get(0);
5042             } else if (N > 1) {
5043                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5044                 // If there is more than one activity with the same priority,
5045                 // then let the user decide between them.
5046                 ResolveInfo r0 = query.get(0);
5047                 ResolveInfo r1 = query.get(1);
5048                 if (DEBUG_INTENT_MATCHING || debug) {
5049                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5050                             + r1.activityInfo.name + "=" + r1.priority);
5051                 }
5052                 // If the first activity has a higher priority, or a different
5053                 // default, then it is always desirable to pick it.
5054                 if (r0.priority != r1.priority
5055                         || r0.preferredOrder != r1.preferredOrder
5056                         || r0.isDefault != r1.isDefault) {
5057                     return query.get(0);
5058                 }
5059                 // If we have saved a preference for a preferred activity for
5060                 // this Intent, use that.
5061                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5062                         flags, query, r0.priority, true, false, debug, userId);
5063                 if (ri != null) {
5064                     return ri;
5065                 }
5066                 ri = new ResolveInfo(mResolveInfo);
5067                 ri.activityInfo = new ActivityInfo(ri.activityInfo);
5068                 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5069                 // If all of the options come from the same package, show the application's
5070                 // label and icon instead of the generic resolver's.
5071                 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5072                 // and then throw away the ResolveInfo itself, meaning that the caller loses
5073                 // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5074                 // a fallback for this case; we only set the target package's resources on
5075                 // the ResolveInfo, not the ActivityInfo.
5076                 final String intentPackage = intent.getPackage();
5077                 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5078                     final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5079                     ri.resolvePackageName = intentPackage;
5080                     if (userNeedsBadging(userId)) {
5081                         ri.noResourceId = true;
5082                     } else {
5083                         ri.icon = appi.icon;
5084                     }
5085                     ri.iconResourceId = appi.icon;
5086                     ri.labelRes = appi.labelRes;
5087                 }
5088                 ri.activityInfo.applicationInfo = new ApplicationInfo(
5089                         ri.activityInfo.applicationInfo);
5090                 if (userId != 0) {
5091                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5092                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5093                 }
5094                 // Make sure that the resolver is displayable in car mode
5095                 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5096                 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5097                 return ri;
5098             }
5099         }
5100         return null;
5101     }
5102
5103     /**
5104      * Return true if the given list is not empty and all of its contents have
5105      * an activityInfo with the given package name.
5106      */
5107     private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5108         if (ArrayUtils.isEmpty(list)) {
5109             return false;
5110         }
5111         for (int i = 0, N = list.size(); i < N; i++) {
5112             final ResolveInfo ri = list.get(i);
5113             final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5114             if (ai == null || !packageName.equals(ai.packageName)) {
5115                 return false;
5116             }
5117         }
5118         return true;
5119     }
5120
5121     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5122             int flags, List<ResolveInfo> query, boolean debug, int userId) {
5123         final int N = query.size();
5124         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5125                 .get(userId);
5126         // Get the list of persistent preferred activities that handle the intent
5127         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5128         List<PersistentPreferredActivity> pprefs = ppir != null
5129                 ? ppir.queryIntent(intent, resolvedType,
5130                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
5131                 : null;
5132         if (pprefs != null && pprefs.size() > 0) {
5133             final int M = pprefs.size();
5134             for (int i=0; i<M; i++) {
5135                 final PersistentPreferredActivity ppa = pprefs.get(i);
5136                 if (DEBUG_PREFERRED || debug) {
5137                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5138                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5139                             + "\n  component=" + ppa.mComponent);
5140                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5141                 }
5142                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5143                         flags | MATCH_DISABLED_COMPONENTS, userId);
5144                 if (DEBUG_PREFERRED || debug) {
5145                     Slog.v(TAG, "Found persistent preferred activity:");
5146                     if (ai != null) {
5147                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5148                     } else {
5149                         Slog.v(TAG, "  null");
5150                     }
5151                 }
5152                 if (ai == null) {
5153                     // This previously registered persistent preferred activity
5154                     // component is no longer known. Ignore it and do NOT remove it.
5155                     continue;
5156                 }
5157                 for (int j=0; j<N; j++) {
5158                     final ResolveInfo ri = query.get(j);
5159                     if (!ri.activityInfo.applicationInfo.packageName
5160                             .equals(ai.applicationInfo.packageName)) {
5161                         continue;
5162                     }
5163                     if (!ri.activityInfo.name.equals(ai.name)) {
5164                         continue;
5165                     }
5166                     //  Found a persistent preference that can handle the intent.
5167                     if (DEBUG_PREFERRED || debug) {
5168                         Slog.v(TAG, "Returning persistent preferred activity: " +
5169                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5170                     }
5171                     return ri;
5172                 }
5173             }
5174         }
5175         return null;
5176     }
5177
5178     // TODO: handle preferred activities missing while user has amnesia
5179     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5180             List<ResolveInfo> query, int priority, boolean always,
5181             boolean removeMatches, boolean debug, int userId) {
5182         if (!sUserManager.exists(userId)) return null;
5183         flags = updateFlagsForResolve(flags, userId, intent);
5184         // writer
5185         synchronized (mPackages) {
5186             if (intent.getSelector() != null) {
5187                 intent = intent.getSelector();
5188             }
5189             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
5190
5191             // Try to find a matching persistent preferred activity.
5192             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5193                     debug, userId);
5194
5195             // If a persistent preferred activity matched, use it.
5196             if (pri != null) {
5197                 return pri;
5198             }
5199
5200             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5201             // Get the list of preferred activities that handle the intent
5202             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5203             List<PreferredActivity> prefs = pir != null
5204                     ? pir.queryIntent(intent, resolvedType,
5205                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
5206                     : null;
5207             if (prefs != null && prefs.size() > 0) {
5208                 boolean changed = false;
5209                 try {
5210                     // First figure out how good the original match set is.
5211                     // We will only allow preferred activities that came
5212                     // from the same match quality.
5213                     int match = 0;
5214
5215                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5216
5217                     final int N = query.size();
5218                     for (int j=0; j<N; j++) {
5219                         final ResolveInfo ri = query.get(j);
5220                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5221                                 + ": 0x" + Integer.toHexString(match));
5222                         if (ri.match > match) {
5223                             match = ri.match;
5224                         }
5225                     }
5226
5227                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5228                             + Integer.toHexString(match));
5229
5230                     match &= IntentFilter.MATCH_CATEGORY_MASK;
5231                     final int M = prefs.size();
5232                     for (int i=0; i<M; i++) {
5233                         final PreferredActivity pa = prefs.get(i);
5234                         if (DEBUG_PREFERRED || debug) {
5235                             Slog.v(TAG, "Checking PreferredActivity ds="
5236                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
5237                                     + "\n  component=" + pa.mPref.mComponent);
5238                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5239                         }
5240                         if (pa.mPref.mMatch != match) {
5241                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
5242                                     + Integer.toHexString(pa.mPref.mMatch));
5243                             continue;
5244                         }
5245                         // If it's not an "always" type preferred activity and that's what we're
5246                         // looking for, skip it.
5247                         if (always && !pa.mPref.mAlways) {
5248                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
5249                             continue;
5250                         }
5251                         final ActivityInfo ai = getActivityInfo(
5252                                 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
5253                                         | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
5254                                 userId);
5255                         if (DEBUG_PREFERRED || debug) {
5256                             Slog.v(TAG, "Found preferred activity:");
5257                             if (ai != null) {
5258                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5259                             } else {
5260                                 Slog.v(TAG, "  null");
5261                             }
5262                         }
5263                         if (ai == null) {
5264                             // This previously registered preferred activity
5265                             // component is no longer known.  Most likely an update
5266                             // to the app was installed and in the new version this
5267                             // component no longer exists.  Clean it up by removing
5268                             // it from the preferred activities list, and skip it.
5269                             Slog.w(TAG, "Removing dangling preferred activity: "
5270                                     + pa.mPref.mComponent);
5271                             pir.removeFilter(pa);
5272                             changed = true;
5273                             continue;
5274                         }
5275                         for (int j=0; j<N; j++) {
5276                             final ResolveInfo ri = query.get(j);
5277                             if (!ri.activityInfo.applicationInfo.packageName
5278                                     .equals(ai.applicationInfo.packageName)) {
5279                                 continue;
5280                             }
5281                             if (!ri.activityInfo.name.equals(ai.name)) {
5282                                 continue;
5283                             }
5284
5285                             if (removeMatches) {
5286                                 pir.removeFilter(pa);
5287                                 changed = true;
5288                                 if (DEBUG_PREFERRED) {
5289                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
5290                                 }
5291                                 break;
5292                             }
5293
5294                             // Okay we found a previously set preferred or last chosen app.
5295                             // If the result set is different from when this
5296                             // was created, we need to clear it and re-ask the
5297                             // user their preference, if we're looking for an "always" type entry.
5298                             if (always && !pa.mPref.sameSet(query)) {
5299                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
5300                                         + intent + " type " + resolvedType);
5301                                 if (DEBUG_PREFERRED) {
5302                                     Slog.v(TAG, "Removing preferred activity since set changed "
5303                                             + pa.mPref.mComponent);
5304                                 }
5305                                 pir.removeFilter(pa);
5306                                 // Re-add the filter as a "last chosen" entry (!always)
5307                                 PreferredActivity lastChosen = new PreferredActivity(
5308                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
5309                                 pir.addFilter(lastChosen);
5310                                 changed = true;
5311                                 return null;
5312                             }
5313
5314                             // Yay! Either the set matched or we're looking for the last chosen
5315                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
5316                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5317                             return ri;
5318                         }
5319                     }
5320                 } finally {
5321                     if (changed) {
5322                         if (DEBUG_PREFERRED) {
5323                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
5324                         }
5325                         scheduleWritePackageRestrictionsLocked(userId);
5326                     }
5327                 }
5328             }
5329         }
5330         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
5331         return null;
5332     }
5333
5334     /*
5335      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
5336      */
5337     @Override
5338     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
5339             int targetUserId) {
5340         mContext.enforceCallingOrSelfPermission(
5341                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
5342         List<CrossProfileIntentFilter> matches =
5343                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
5344         if (matches != null) {
5345             int size = matches.size();
5346             for (int i = 0; i < size; i++) {
5347                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
5348             }
5349         }
5350         if (hasWebURI(intent)) {
5351             // cross-profile app linking works only towards the parent.
5352             final UserInfo parent = getProfileParent(sourceUserId);
5353             synchronized(mPackages) {
5354                 int flags = updateFlagsForResolve(0, parent.id, intent);
5355                 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
5356                         intent, resolvedType, flags, sourceUserId, parent.id);
5357                 return xpDomainInfo != null;
5358             }
5359         }
5360         return false;
5361     }
5362
5363     private UserInfo getProfileParent(int userId) {
5364         final long identity = Binder.clearCallingIdentity();
5365         try {
5366             return sUserManager.getProfileParent(userId);
5367         } finally {
5368             Binder.restoreCallingIdentity(identity);
5369         }
5370     }
5371
5372     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
5373             String resolvedType, int userId) {
5374         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
5375         if (resolver != null) {
5376             return resolver.queryIntent(intent, resolvedType, false, userId);
5377         }
5378         return null;
5379     }
5380
5381     @Override
5382     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
5383             String resolvedType, int flags, int userId) {
5384         try {
5385             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5386
5387             return new ParceledListSlice<>(
5388                     queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
5389         } finally {
5390             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5391         }
5392     }
5393
5394     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5395             String resolvedType, int flags, int userId) {
5396         if (!sUserManager.exists(userId)) return Collections.emptyList();
5397         flags = updateFlagsForResolve(flags, userId, intent);
5398         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5399                 false /* requireFullPermission */, false /* checkShell */,
5400                 "query intent activities");
5401         ComponentName comp = intent.getComponent();
5402         if (comp == null) {
5403             if (intent.getSelector() != null) {
5404                 intent = intent.getSelector();
5405                 comp = intent.getComponent();
5406             }
5407         }
5408
5409         if (comp != null) {
5410             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5411             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
5412             if (ai != null) {
5413                 final ResolveInfo ri = new ResolveInfo();
5414                 ri.activityInfo = ai;
5415                 list.add(ri);
5416             }
5417             return list;
5418         }
5419
5420         // reader
5421         boolean sortResult = false;
5422         boolean addEphemeral = false;
5423         boolean matchEphemeralPackage = false;
5424         List<ResolveInfo> result;
5425         final String pkgName = intent.getPackage();
5426         synchronized (mPackages) {
5427             if (pkgName == null) {
5428                 List<CrossProfileIntentFilter> matchingFilters =
5429                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
5430                 // Check for results that need to skip the current profile.
5431                 ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
5432                         resolvedType, flags, userId);
5433                 if (xpResolveInfo != null) {
5434                     List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
5435                     xpResult.add(xpResolveInfo);
5436                     return filterIfNotSystemUser(xpResult, userId);
5437                 }
5438
5439                 // Check for results in the current profile.
5440                 result = filterIfNotSystemUser(mActivities.queryIntent(
5441                         intent, resolvedType, flags, userId), userId);
5442                 addEphemeral =
5443                         isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
5444
5445                 // Check for cross profile results.
5446                 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
5447                 xpResolveInfo = queryCrossProfileIntents(
5448                         matchingFilters, intent, resolvedType, flags, userId,
5449                         hasNonNegativePriorityResult);
5450                 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
5451                     boolean isVisibleToUser = filterIfNotSystemUser(
5452                             Collections.singletonList(xpResolveInfo), userId).size() > 0;
5453                     if (isVisibleToUser) {
5454                         result.add(xpResolveInfo);
5455                         sortResult = true;
5456                     }
5457                 }
5458                 if (hasWebURI(intent)) {
5459                     CrossProfileDomainInfo xpDomainInfo = null;
5460                     final UserInfo parent = getProfileParent(userId);
5461                     if (parent != null) {
5462                         xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
5463                                 flags, userId, parent.id);
5464                     }
5465                     if (xpDomainInfo != null) {
5466                         if (xpResolveInfo != null) {
5467                             // If we didn't remove it, the cross-profile ResolveInfo would be twice
5468                             // in the result.
5469                             result.remove(xpResolveInfo);
5470                         }
5471                         if (result.size() == 0 && !addEphemeral) {
5472                             result.add(xpDomainInfo.resolveInfo);
5473                             return result;
5474                         }
5475                     }
5476                     if (result.size() > 1 || addEphemeral) {
5477                         result = filterCandidatesWithDomainPreferredActivitiesLPr(
5478                                 intent, flags, result, xpDomainInfo, userId);
5479                         sortResult = true;
5480                     }
5481                 }
5482             } else {
5483                 final PackageParser.Package pkg = mPackages.get(pkgName);
5484                 if (pkg != null) {
5485                     result = filterIfNotSystemUser(
5486                             mActivities.queryIntentForPackage(
5487                                     intent, resolvedType, flags, pkg.activities, userId),
5488                             userId);
5489                 } else {
5490                     // the caller wants to resolve for a particular package; however, there
5491                     // were no installed results, so, try to find an ephemeral result
5492                     addEphemeral = isEphemeralAllowed(
5493                             intent, null /*result*/, userId, true /*skipPackageCheck*/);
5494                     matchEphemeralPackage = true;
5495                     result = new ArrayList<ResolveInfo>();
5496                 }
5497             }
5498         }
5499         if (addEphemeral) {
5500             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
5501             final EphemeralResolveInfo ai = getEphemeralResolveInfo(
5502                     mContext, mEphemeralResolverConnection, intent, resolvedType, userId,
5503                     matchEphemeralPackage ? pkgName : null);
5504             if (ai != null) {
5505                 if (DEBUG_EPHEMERAL) {
5506                     Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
5507                 }
5508                 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
5509                 ephemeralInstaller.ephemeralResolveInfo = ai;
5510                 // make sure this resolver is the default
5511                 ephemeralInstaller.isDefault = true;
5512                 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
5513                         | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
5514                 // add a non-generic filter
5515                 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
5516                 ephemeralInstaller.filter.addDataPath(
5517                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
5518                 result.add(ephemeralInstaller);
5519             }
5520             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5521         }
5522         if (sortResult) {
5523             Collections.sort(result, mResolvePrioritySorter);
5524         }
5525         return result;
5526     }
5527
5528     private static class CrossProfileDomainInfo {
5529         /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
5530         ResolveInfo resolveInfo;
5531         /* Best domain verification status of the activities found in the other profile */
5532         int bestDomainVerificationStatus;
5533     }
5534
5535     private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5536             String resolvedType, int flags, int sourceUserId, int parentUserId) {
5537         if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
5538                 sourceUserId)) {
5539             return null;
5540         }
5541         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5542                 resolvedType, flags, parentUserId);
5543
5544         if (resultTargetUser == null || resultTargetUser.isEmpty()) {
5545             return null;
5546         }
5547         CrossProfileDomainInfo result = null;
5548         int size = resultTargetUser.size();
5549         for (int i = 0; i < size; i++) {
5550             ResolveInfo riTargetUser = resultTargetUser.get(i);
5551             // Intent filter verification is only for filters that specify a host. So don't return
5552             // those that handle all web uris.
5553             if (riTargetUser.handleAllWebDataURI) {
5554                 continue;
5555             }
5556             String packageName = riTargetUser.activityInfo.packageName;
5557             PackageSetting ps = mSettings.mPackages.get(packageName);
5558             if (ps == null) {
5559                 continue;
5560             }
5561             long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
5562             int status = (int)(verificationState >> 32);
5563             if (result == null) {
5564                 result = new CrossProfileDomainInfo();
5565                 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5566                         sourceUserId, parentUserId);
5567                 result.bestDomainVerificationStatus = status;
5568             } else {
5569                 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5570                         result.bestDomainVerificationStatus);
5571             }
5572         }
5573         // Don't consider matches with status NEVER across profiles.
5574         if (result != null && result.bestDomainVerificationStatus
5575                 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5576             return null;
5577         }
5578         return result;
5579     }
5580
5581     /**
5582      * Verification statuses are ordered from the worse to the best, except for
5583      * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5584      */
5585     private int bestDomainVerificationStatus(int status1, int status2) {
5586         if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5587             return status2;
5588         }
5589         if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5590             return status1;
5591         }
5592         return (int) MathUtils.max(status1, status2);
5593     }
5594
5595     private boolean isUserEnabled(int userId) {
5596         long callingId = Binder.clearCallingIdentity();
5597         try {
5598             UserInfo userInfo = sUserManager.getUserInfo(userId);
5599             return userInfo != null && userInfo.isEnabled();
5600         } finally {
5601             Binder.restoreCallingIdentity(callingId);
5602         }
5603     }
5604
5605     /**
5606      * Filter out activities with systemUserOnly flag set, when current user is not System.
5607      *
5608      * @return filtered list
5609      */
5610     private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5611         if (userId == UserHandle.USER_SYSTEM) {
5612             return resolveInfos;
5613         }
5614         for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5615             ResolveInfo info = resolveInfos.get(i);
5616             if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5617                 resolveInfos.remove(i);
5618             }
5619         }
5620         return resolveInfos;
5621     }
5622
5623     /**
5624      * @param resolveInfos list of resolve infos in descending priority order
5625      * @return if the list contains a resolve info with non-negative priority
5626      */
5627     private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5628         return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5629     }
5630
5631     private static boolean hasWebURI(Intent intent) {
5632         if (intent.getData() == null) {
5633             return false;
5634         }
5635         final String scheme = intent.getScheme();
5636         if (TextUtils.isEmpty(scheme)) {
5637             return false;
5638         }
5639         return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5640     }
5641
5642     private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5643             int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5644             int userId) {
5645         final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5646
5647         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5648             Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5649                     candidates.size());
5650         }
5651
5652         ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5653         ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5654         ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5655         ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5656         ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5657         ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5658
5659         synchronized (mPackages) {
5660             final int count = candidates.size();
5661             // First, try to use linked apps. Partition the candidates into four lists:
5662             // one for the final results, one for the "do not use ever", one for "undefined status"
5663             // and finally one for "browser app type".
5664             for (int n=0; n<count; n++) {
5665                 ResolveInfo info = candidates.get(n);
5666                 String packageName = info.activityInfo.packageName;
5667                 PackageSetting ps = mSettings.mPackages.get(packageName);
5668                 if (ps != null) {
5669                     // Add to the special match all list (Browser use case)
5670                     if (info.handleAllWebDataURI) {
5671                         matchAllList.add(info);
5672                         continue;
5673                     }
5674                     // Try to get the status from User settings first
5675                     long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5676                     int status = (int)(packedStatus >> 32);
5677                     int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5678                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5679                         if (DEBUG_DOMAIN_VERIFICATION) {
5680                             Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5681                                     + " : linkgen=" + linkGeneration);
5682                         }
5683                         // Use link-enabled generation as preferredOrder, i.e.
5684                         // prefer newly-enabled over earlier-enabled.
5685                         info.preferredOrder = linkGeneration;
5686                         alwaysList.add(info);
5687                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5688                         if (DEBUG_DOMAIN_VERIFICATION) {
5689                             Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5690                         }
5691                         neverList.add(info);
5692                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5693                         if (DEBUG_DOMAIN_VERIFICATION) {
5694                             Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5695                         }
5696                         alwaysAskList.add(info);
5697                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5698                             status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5699                         if (DEBUG_DOMAIN_VERIFICATION) {
5700                             Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5701                         }
5702                         undefinedList.add(info);
5703                     }
5704                 }
5705             }
5706
5707             // We'll want to include browser possibilities in a few cases
5708             boolean includeBrowser = false;
5709
5710             // First try to add the "always" resolution(s) for the current user, if any
5711             if (alwaysList.size() > 0) {
5712                 result.addAll(alwaysList);
5713             } else {
5714                 // Add all undefined apps as we want them to appear in the disambiguation dialog.
5715                 result.addAll(undefinedList);
5716                 // Maybe add one for the other profile.
5717                 if (xpDomainInfo != null && (
5718                         xpDomainInfo.bestDomainVerificationStatus
5719                         != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5720                     result.add(xpDomainInfo.resolveInfo);
5721                 }
5722                 includeBrowser = true;
5723             }
5724
5725             // The presence of any 'always ask' alternatives means we'll also offer browsers.
5726             // If there were 'always' entries their preferred order has been set, so we also
5727             // back that off to make the alternatives equivalent
5728             if (alwaysAskList.size() > 0) {
5729                 for (ResolveInfo i : result) {
5730                     i.preferredOrder = 0;
5731                 }
5732                 result.addAll(alwaysAskList);
5733                 includeBrowser = true;
5734             }
5735
5736             if (includeBrowser) {
5737                 // Also add browsers (all of them or only the default one)
5738                 if (DEBUG_DOMAIN_VERIFICATION) {
5739                     Slog.v(TAG, "   ...including browsers in candidate set");
5740                 }
5741                 if ((matchFlags & MATCH_ALL) != 0) {
5742                     result.addAll(matchAllList);
5743                 } else {
5744                     // Browser/generic handling case.  If there's a default browser, go straight
5745                     // to that (but only if there is no other higher-priority match).
5746                     final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5747                     int maxMatchPrio = 0;
5748                     ResolveInfo defaultBrowserMatch = null;
5749                     final int numCandidates = matchAllList.size();
5750                     for (int n = 0; n < numCandidates; n++) {
5751                         ResolveInfo info = matchAllList.get(n);
5752                         // track the highest overall match priority...
5753                         if (info.priority > maxMatchPrio) {
5754                             maxMatchPrio = info.priority;
5755                         }
5756                         // ...and the highest-priority default browser match
5757                         if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5758                             if (defaultBrowserMatch == null
5759                                     || (defaultBrowserMatch.priority < info.priority)) {
5760                                 if (debug) {
5761                                     Slog.v(TAG, "Considering default browser match " + info);
5762                                 }
5763                                 defaultBrowserMatch = info;
5764                             }
5765                         }
5766                     }
5767                     if (defaultBrowserMatch != null
5768                             && defaultBrowserMatch.priority >= maxMatchPrio
5769                             && !TextUtils.isEmpty(defaultBrowserPackageName))
5770                     {
5771                         if (debug) {
5772                             Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5773                         }
5774                         result.add(defaultBrowserMatch);
5775                     } else {
5776                         result.addAll(matchAllList);
5777                     }
5778                 }
5779
5780                 // If there is nothing selected, add all candidates and remove the ones that the user
5781                 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5782                 if (result.size() == 0) {
5783                     result.addAll(candidates);
5784                     result.removeAll(neverList);
5785                 }
5786             }
5787         }
5788         if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5789             Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5790                     result.size());
5791             for (ResolveInfo info : result) {
5792                 Slog.v(TAG, "  + " + info.activityInfo);
5793             }
5794         }
5795         return result;
5796     }
5797
5798     // Returns a packed value as a long:
5799     //
5800     // high 'int'-sized word: link status: undefined/ask/never/always.
5801     // low 'int'-sized word: relative priority among 'always' results.
5802     private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5803         long result = ps.getDomainVerificationStatusForUser(userId);
5804         // if none available, get the master status
5805         if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5806             if (ps.getIntentFilterVerificationInfo() != null) {
5807                 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5808             }
5809         }
5810         return result;
5811     }
5812
5813     private ResolveInfo querySkipCurrentProfileIntents(
5814             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5815             int flags, int sourceUserId) {
5816         if (matchingFilters != null) {
5817             int size = matchingFilters.size();
5818             for (int i = 0; i < size; i ++) {
5819                 CrossProfileIntentFilter filter = matchingFilters.get(i);
5820                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5821                     // Checking if there are activities in the target user that can handle the
5822                     // intent.
5823                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5824                             resolvedType, flags, sourceUserId);
5825                     if (resolveInfo != null) {
5826                         return resolveInfo;
5827                     }
5828                 }
5829             }
5830         }
5831         return null;
5832     }
5833
5834     // Return matching ResolveInfo in target user if any.
5835     private ResolveInfo queryCrossProfileIntents(
5836             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5837             int flags, int sourceUserId, boolean matchInCurrentProfile) {
5838         if (matchingFilters != null) {
5839             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5840             // match the same intent. For performance reasons, it is better not to
5841             // run queryIntent twice for the same userId
5842             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5843             int size = matchingFilters.size();
5844             for (int i = 0; i < size; i++) {
5845                 CrossProfileIntentFilter filter = matchingFilters.get(i);
5846                 int targetUserId = filter.getTargetUserId();
5847                 boolean skipCurrentProfile =
5848                         (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5849                 boolean skipCurrentProfileIfNoMatchFound =
5850                         (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5851                 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5852                         && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5853                     // Checking if there are activities in the target user that can handle the
5854                     // intent.
5855                     ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5856                             resolvedType, flags, sourceUserId);
5857                     if (resolveInfo != null) return resolveInfo;
5858                     alreadyTriedUserIds.put(targetUserId, true);
5859                 }
5860             }
5861         }
5862         return null;
5863     }
5864
5865     /**
5866      * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5867      * will forward the intent to the filter's target user.
5868      * Otherwise, returns null.
5869      */
5870     private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5871             String resolvedType, int flags, int sourceUserId) {
5872         int targetUserId = filter.getTargetUserId();
5873         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5874                 resolvedType, flags, targetUserId);
5875         if (resultTargetUser != null && isUserEnabled(targetUserId)) {
5876             // If all the matches in the target profile are suspended, return null.
5877             for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
5878                 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
5879                         & ApplicationInfo.FLAG_SUSPENDED) == 0) {
5880                     return createForwardingResolveInfoUnchecked(filter, sourceUserId,
5881                             targetUserId);
5882                 }
5883             }
5884         }
5885         return null;
5886     }
5887
5888     private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5889             int sourceUserId, int targetUserId) {
5890         ResolveInfo forwardingResolveInfo = new ResolveInfo();
5891         long ident = Binder.clearCallingIdentity();
5892         boolean targetIsProfile;
5893         try {
5894             targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5895         } finally {
5896             Binder.restoreCallingIdentity(ident);
5897         }
5898         String className;
5899         if (targetIsProfile) {
5900             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5901         } else {
5902             className = FORWARD_INTENT_TO_PARENT;
5903         }
5904         ComponentName forwardingActivityComponentName = new ComponentName(
5905                 mAndroidApplication.packageName, className);
5906         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5907                 sourceUserId);
5908         if (!targetIsProfile) {
5909             forwardingActivityInfo.showUserIcon = targetUserId;
5910             forwardingResolveInfo.noResourceId = true;
5911         }
5912         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5913         forwardingResolveInfo.priority = 0;
5914         forwardingResolveInfo.preferredOrder = 0;
5915         forwardingResolveInfo.match = 0;
5916         forwardingResolveInfo.isDefault = true;
5917         forwardingResolveInfo.filter = filter;
5918         forwardingResolveInfo.targetUserId = targetUserId;
5919         return forwardingResolveInfo;
5920     }
5921
5922     @Override
5923     public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5924             Intent[] specifics, String[] specificTypes, Intent intent,
5925             String resolvedType, int flags, int userId) {
5926         return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
5927                 specificTypes, intent, resolvedType, flags, userId));
5928     }
5929
5930     private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
5931             Intent[] specifics, String[] specificTypes, Intent intent,
5932             String resolvedType, int flags, int userId) {
5933         if (!sUserManager.exists(userId)) return Collections.emptyList();
5934         flags = updateFlagsForResolve(flags, userId, intent);
5935         enforceCrossUserPermission(Binder.getCallingUid(), userId,
5936                 false /* requireFullPermission */, false /* checkShell */,
5937                 "query intent activity options");
5938         final String resultsAction = intent.getAction();
5939
5940         final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
5941                 | PackageManager.GET_RESOLVED_FILTER, userId);
5942
5943         if (DEBUG_INTENT_MATCHING) {
5944             Log.v(TAG, "Query " + intent + ": " + results);
5945         }
5946
5947         int specificsPos = 0;
5948         int N;
5949
5950         // todo: note that the algorithm used here is O(N^2).  This
5951         // isn't a problem in our current environment, but if we start running
5952         // into situations where we have more than 5 or 10 matches then this
5953         // should probably be changed to something smarter...
5954
5955         // First we go through and resolve each of the specific items
5956         // that were supplied, taking care of removing any corresponding
5957         // duplicate items in the generic resolve list.
5958         if (specifics != null) {
5959             for (int i=0; i<specifics.length; i++) {
5960                 final Intent sintent = specifics[i];
5961                 if (sintent == null) {
5962                     continue;
5963                 }
5964
5965                 if (DEBUG_INTENT_MATCHING) {
5966                     Log.v(TAG, "Specific #" + i + ": " + sintent);
5967                 }
5968
5969                 String action = sintent.getAction();
5970                 if (resultsAction != null && resultsAction.equals(action)) {
5971                     // If this action was explicitly requested, then don't
5972                     // remove things that have it.
5973                     action = null;
5974                 }
5975
5976                 ResolveInfo ri = null;
5977                 ActivityInfo ai = null;
5978
5979                 ComponentName comp = sintent.getComponent();
5980                 if (comp == null) {
5981                     ri = resolveIntent(
5982                         sintent,
5983                         specificTypes != null ? specificTypes[i] : null,
5984                             flags, userId);
5985                     if (ri == null) {
5986                         continue;
5987                     }
5988                     if (ri == mResolveInfo) {
5989                         // ACK!  Must do something better with this.
5990                     }
5991                     ai = ri.activityInfo;
5992                     comp = new ComponentName(ai.applicationInfo.packageName,
5993                             ai.name);
5994                 } else {
5995                     ai = getActivityInfo(comp, flags, userId);
5996                     if (ai == null) {
5997                         continue;
5998                     }
5999                 }
6000
6001                 // Look for any generic query activities that are duplicates
6002                 // of this specific one, and remove them from the results.
6003                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6004                 N = results.size();
6005                 int j;
6006                 for (j=specificsPos; j<N; j++) {
6007                     ResolveInfo sri = results.get(j);
6008                     if ((sri.activityInfo.name.equals(comp.getClassName())
6009                             && sri.activityInfo.applicationInfo.packageName.equals(
6010                                     comp.getPackageName()))
6011                         || (action != null && sri.filter.matchAction(action))) {
6012                         results.remove(j);
6013                         if (DEBUG_INTENT_MATCHING) Log.v(
6014                             TAG, "Removing duplicate item from " + j
6015                             + " due to specific " + specificsPos);
6016                         if (ri == null) {
6017                             ri = sri;
6018                         }
6019                         j--;
6020                         N--;
6021                     }
6022                 }
6023
6024                 // Add this specific item to its proper place.
6025                 if (ri == null) {
6026                     ri = new ResolveInfo();
6027                     ri.activityInfo = ai;
6028                 }
6029                 results.add(specificsPos, ri);
6030                 ri.specificIndex = i;
6031                 specificsPos++;
6032             }
6033         }
6034
6035         // Now we go through the remaining generic results and remove any
6036         // duplicate actions that are found here.
6037         N = results.size();
6038         for (int i=specificsPos; i<N-1; i++) {
6039             final ResolveInfo rii = results.get(i);
6040             if (rii.filter == null) {
6041                 continue;
6042             }
6043
6044             // Iterate over all of the actions of this result's intent
6045             // filter...  typically this should be just one.
6046             final Iterator<String> it = rii.filter.actionsIterator();
6047             if (it == null) {
6048                 continue;
6049             }
6050             while (it.hasNext()) {
6051                 final String action = it.next();
6052                 if (resultsAction != null && resultsAction.equals(action)) {
6053                     // If this action was explicitly requested, then don't
6054                     // remove things that have it.
6055                     continue;
6056                 }
6057                 for (int j=i+1; j<N; j++) {
6058                     final ResolveInfo rij = results.get(j);
6059                     if (rij.filter != null && rij.filter.hasAction(action)) {
6060                         results.remove(j);
6061                         if (DEBUG_INTENT_MATCHING) Log.v(
6062                             TAG, "Removing duplicate item from " + j
6063                             + " due to action " + action + " at " + i);
6064                         j--;
6065                         N--;
6066                     }
6067                 }
6068             }
6069
6070             // If the caller didn't request filter information, drop it now
6071             // so we don't have to marshall/unmarshall it.
6072             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6073                 rii.filter = null;
6074             }
6075         }
6076
6077         // Filter out the caller activity if so requested.
6078         if (caller != null) {
6079             N = results.size();
6080             for (int i=0; i<N; i++) {
6081                 ActivityInfo ainfo = results.get(i).activityInfo;
6082                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6083                         && caller.getClassName().equals(ainfo.name)) {
6084                     results.remove(i);
6085                     break;
6086                 }
6087             }
6088         }
6089
6090         // If the caller didn't request filter information,
6091         // drop them now so we don't have to
6092         // marshall/unmarshall it.
6093         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6094             N = results.size();
6095             for (int i=0; i<N; i++) {
6096                 results.get(i).filter = null;
6097             }
6098         }
6099
6100         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
6101         return results;
6102     }
6103
6104     @Override
6105     public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
6106             String resolvedType, int flags, int userId) {
6107         return new ParceledListSlice<>(
6108                 queryIntentReceiversInternal(intent, resolvedType, flags, userId));
6109     }
6110
6111     private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
6112             String resolvedType, int flags, int userId) {
6113         if (!sUserManager.exists(userId)) return Collections.emptyList();
6114         flags = updateFlagsForResolve(flags, userId, intent);
6115         ComponentName comp = intent.getComponent();
6116         if (comp == null) {
6117             if (intent.getSelector() != null) {
6118                 intent = intent.getSelector();
6119                 comp = intent.getComponent();
6120             }
6121         }
6122         if (comp != null) {
6123             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6124             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
6125             if (ai != null) {
6126                 ResolveInfo ri = new ResolveInfo();
6127                 ri.activityInfo = ai;
6128                 list.add(ri);
6129             }
6130             return list;
6131         }
6132
6133         // reader
6134         synchronized (mPackages) {
6135             String pkgName = intent.getPackage();
6136             if (pkgName == null) {
6137                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
6138             }
6139             final PackageParser.Package pkg = mPackages.get(pkgName);
6140             if (pkg != null) {
6141                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
6142                         userId);
6143             }
6144             return Collections.emptyList();
6145         }
6146     }
6147
6148     @Override
6149     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
6150         if (!sUserManager.exists(userId)) return null;
6151         flags = updateFlagsForResolve(flags, userId, intent);
6152         List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
6153         if (query != null) {
6154             if (query.size() >= 1) {
6155                 // If there is more than one service with the same priority,
6156                 // just arbitrarily pick the first one.
6157                 return query.get(0);
6158             }
6159         }
6160         return null;
6161     }
6162
6163     @Override
6164     public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
6165             String resolvedType, int flags, int userId) {
6166         return new ParceledListSlice<>(
6167                 queryIntentServicesInternal(intent, resolvedType, flags, userId));
6168     }
6169
6170     private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
6171             String resolvedType, int flags, int userId) {
6172         if (!sUserManager.exists(userId)) return Collections.emptyList();
6173         flags = updateFlagsForResolve(flags, userId, intent);
6174         ComponentName comp = intent.getComponent();
6175         if (comp == null) {
6176             if (intent.getSelector() != null) {
6177                 intent = intent.getSelector();
6178                 comp = intent.getComponent();
6179             }
6180         }
6181         if (comp != null) {
6182             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6183             final ServiceInfo si = getServiceInfo(comp, flags, userId);
6184             if (si != null) {
6185                 final ResolveInfo ri = new ResolveInfo();
6186                 ri.serviceInfo = si;
6187                 list.add(ri);
6188             }
6189             return list;
6190         }
6191
6192         // reader
6193         synchronized (mPackages) {
6194             String pkgName = intent.getPackage();
6195             if (pkgName == null) {
6196                 return mServices.queryIntent(intent, resolvedType, flags, userId);
6197             }
6198             final PackageParser.Package pkg = mPackages.get(pkgName);
6199             if (pkg != null) {
6200                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
6201                         userId);
6202             }
6203             return Collections.emptyList();
6204         }
6205     }
6206
6207     @Override
6208     public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
6209             String resolvedType, int flags, int userId) {
6210         return new ParceledListSlice<>(
6211                 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
6212     }
6213
6214     private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
6215             Intent intent, String resolvedType, int flags, int userId) {
6216         if (!sUserManager.exists(userId)) return Collections.emptyList();
6217         flags = updateFlagsForResolve(flags, userId, intent);
6218         ComponentName comp = intent.getComponent();
6219         if (comp == null) {
6220             if (intent.getSelector() != null) {
6221                 intent = intent.getSelector();
6222                 comp = intent.getComponent();
6223             }
6224         }
6225         if (comp != null) {
6226             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6227             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
6228             if (pi != null) {
6229                 final ResolveInfo ri = new ResolveInfo();
6230                 ri.providerInfo = pi;
6231                 list.add(ri);
6232             }
6233             return list;
6234         }
6235
6236         // reader
6237         synchronized (mPackages) {
6238             String pkgName = intent.getPackage();
6239             if (pkgName == null) {
6240                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
6241             }
6242             final PackageParser.Package pkg = mPackages.get(pkgName);
6243             if (pkg != null) {
6244                 return mProviders.queryIntentForPackage(
6245                         intent, resolvedType, flags, pkg.providers, userId);
6246             }
6247             return Collections.emptyList();
6248         }
6249     }
6250
6251     @Override
6252     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
6253         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6254         flags = updateFlagsForPackage(flags, userId, null);
6255         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6256         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6257                 false /* requireFullPermission */, false /* checkShell */,
6258                 "get installed packages");
6259
6260         // writer
6261         synchronized (mPackages) {
6262             ArrayList<PackageInfo> list;
6263             if (listUninstalled) {
6264                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
6265                 for (PackageSetting ps : mSettings.mPackages.values()) {
6266                     final PackageInfo pi;
6267                     if (ps.pkg != null) {
6268                         pi = generatePackageInfo(ps, flags, userId);
6269                     } else {
6270                         pi = generatePackageInfo(ps, flags, userId);
6271                     }
6272                     if (pi != null) {
6273                         list.add(pi);
6274                     }
6275                 }
6276             } else {
6277                 list = new ArrayList<PackageInfo>(mPackages.size());
6278                 for (PackageParser.Package p : mPackages.values()) {
6279                     final PackageInfo pi =
6280                             generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
6281                     if (pi != null) {
6282                         list.add(pi);
6283                     }
6284                 }
6285             }
6286
6287             return new ParceledListSlice<PackageInfo>(list);
6288         }
6289     }
6290
6291     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
6292             String[] permissions, boolean[] tmp, int flags, int userId) {
6293         int numMatch = 0;
6294         final PermissionsState permissionsState = ps.getPermissionsState();
6295         for (int i=0; i<permissions.length; i++) {
6296             final String permission = permissions[i];
6297             if (permissionsState.hasPermission(permission, userId)) {
6298                 tmp[i] = true;
6299                 numMatch++;
6300             } else {
6301                 tmp[i] = false;
6302             }
6303         }
6304         if (numMatch == 0) {
6305             return;
6306         }
6307         final PackageInfo pi;
6308         if (ps.pkg != null) {
6309             pi = generatePackageInfo(ps, flags, userId);
6310         } else {
6311             pi = generatePackageInfo(ps, flags, userId);
6312         }
6313         // The above might return null in cases of uninstalled apps or install-state
6314         // skew across users/profiles.
6315         if (pi != null) {
6316             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
6317                 if (numMatch == permissions.length) {
6318                     pi.requestedPermissions = permissions;
6319                 } else {
6320                     pi.requestedPermissions = new String[numMatch];
6321                     numMatch = 0;
6322                     for (int i=0; i<permissions.length; i++) {
6323                         if (tmp[i]) {
6324                             pi.requestedPermissions[numMatch] = permissions[i];
6325                             numMatch++;
6326                         }
6327                     }
6328                 }
6329             }
6330             list.add(pi);
6331         }
6332     }
6333
6334     @Override
6335     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
6336             String[] permissions, int flags, int userId) {
6337         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6338         flags = updateFlagsForPackage(flags, userId, permissions);
6339         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6340
6341         // writer
6342         synchronized (mPackages) {
6343             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
6344             boolean[] tmpBools = new boolean[permissions.length];
6345             if (listUninstalled) {
6346                 for (PackageSetting ps : mSettings.mPackages.values()) {
6347                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
6348                 }
6349             } else {
6350                 for (PackageParser.Package pkg : mPackages.values()) {
6351                     PackageSetting ps = (PackageSetting)pkg.mExtras;
6352                     if (ps != null) {
6353                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
6354                                 userId);
6355                     }
6356                 }
6357             }
6358
6359             return new ParceledListSlice<PackageInfo>(list);
6360         }
6361     }
6362
6363     @Override
6364     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
6365         final int callingUid = Binder.getCallingUid();
6366         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6367         flags = updateFlagsForApplication(flags, userId, null);
6368         final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6369
6370         enforceCrossUserPermission(
6371             callingUid,
6372             userId,
6373             false /* requireFullPermission */,
6374             false /* checkShell */,
6375             "get installed application info");
6376
6377         // writer
6378         synchronized (mPackages) {
6379             ArrayList<ApplicationInfo> list;
6380             if (listUninstalled) {
6381                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
6382                 for (PackageSetting ps : mSettings.mPackages.values()) {
6383                     ApplicationInfo ai;
6384                     if (ps.pkg != null) {
6385                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
6386                                 ps.readUserState(userId), userId);
6387                     } else {
6388                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
6389                     }
6390                     if (ai != null) {
6391                         list.add(ai);
6392                     }
6393                 }
6394             } else {
6395                 list = new ArrayList<ApplicationInfo>(mPackages.size());
6396                 for (PackageParser.Package p : mPackages.values()) {
6397                     if (p.mExtras != null) {
6398                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6399                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
6400                         if (ai != null) {
6401                             list.add(ai);
6402                         }
6403                     }
6404                 }
6405             }
6406
6407             return new ParceledListSlice<ApplicationInfo>(list);
6408         }
6409     }
6410
6411     @Override
6412     public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
6413         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6414             return null;
6415         }
6416
6417         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6418                 "getEphemeralApplications");
6419         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6420                 true /* requireFullPermission */, false /* checkShell */,
6421                 "getEphemeralApplications");
6422         synchronized (mPackages) {
6423             List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
6424                     .getEphemeralApplicationsLPw(userId);
6425             if (ephemeralApps != null) {
6426                 return new ParceledListSlice<>(ephemeralApps);
6427             }
6428         }
6429         return null;
6430     }
6431
6432     @Override
6433     public boolean isEphemeralApplication(String packageName, int userId) {
6434         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6435                 true /* requireFullPermission */, false /* checkShell */,
6436                 "isEphemeral");
6437         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6438             return false;
6439         }
6440
6441         if (!isCallerSameApp(packageName)) {
6442             return false;
6443         }
6444         synchronized (mPackages) {
6445             PackageParser.Package pkg = mPackages.get(packageName);
6446             if (pkg != null) {
6447                 return pkg.applicationInfo.isEphemeralApp();
6448             }
6449         }
6450         return false;
6451     }
6452
6453     @Override
6454     public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
6455         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6456             return null;
6457         }
6458
6459         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6460                 true /* requireFullPermission */, false /* checkShell */,
6461                 "getCookie");
6462         if (!isCallerSameApp(packageName)) {
6463             return null;
6464         }
6465         synchronized (mPackages) {
6466             return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
6467                     packageName, userId);
6468         }
6469     }
6470
6471     @Override
6472     public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
6473         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6474             return true;
6475         }
6476
6477         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6478                 true /* requireFullPermission */, true /* checkShell */,
6479                 "setCookie");
6480         if (!isCallerSameApp(packageName)) {
6481             return false;
6482         }
6483         synchronized (mPackages) {
6484             return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
6485                     packageName, cookie, userId);
6486         }
6487     }
6488
6489     @Override
6490     public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
6491         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6492             return null;
6493         }
6494
6495         mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6496                 "getEphemeralApplicationIcon");
6497         enforceCrossUserPermission(Binder.getCallingUid(), userId,
6498                 true /* requireFullPermission */, false /* checkShell */,
6499                 "getEphemeralApplicationIcon");
6500         synchronized (mPackages) {
6501             return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
6502                     packageName, userId);
6503         }
6504     }
6505
6506     private boolean isCallerSameApp(String packageName) {
6507         PackageParser.Package pkg = mPackages.get(packageName);
6508         return pkg != null
6509                 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
6510     }
6511
6512     @Override
6513     public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
6514         return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
6515     }
6516
6517     private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
6518         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
6519
6520         // reader
6521         synchronized (mPackages) {
6522             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
6523             final int userId = UserHandle.getCallingUserId();
6524             while (i.hasNext()) {
6525                 final PackageParser.Package p = i.next();
6526                 if (p.applicationInfo == null) continue;
6527
6528                 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
6529                         && !p.applicationInfo.isDirectBootAware();
6530                 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
6531                         && p.applicationInfo.isDirectBootAware();
6532
6533                 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
6534                         && (!mSafeMode || isSystemApp(p))
6535                         && (matchesUnaware || matchesAware)) {
6536                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
6537                     if (ps != null) {
6538                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6539                                 ps.readUserState(userId), userId);
6540                         if (ai != null) {
6541                             finalList.add(ai);
6542                         }
6543                     }
6544                 }
6545             }
6546         }
6547
6548         return finalList;
6549     }
6550
6551     @Override
6552     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
6553         if (!sUserManager.exists(userId)) return null;
6554         flags = updateFlagsForComponent(flags, userId, name);
6555         // reader
6556         synchronized (mPackages) {
6557             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
6558             PackageSetting ps = provider != null
6559                     ? mSettings.mPackages.get(provider.owner.packageName)
6560                     : null;
6561             return ps != null
6562                     && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
6563                     ? PackageParser.generateProviderInfo(provider, flags,
6564                             ps.readUserState(userId), userId)
6565                     : null;
6566         }
6567     }
6568
6569     /**
6570      * @deprecated
6571      */
6572     @Deprecated
6573     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
6574         // reader
6575         synchronized (mPackages) {
6576             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
6577                     .entrySet().iterator();
6578             final int userId = UserHandle.getCallingUserId();
6579             while (i.hasNext()) {
6580                 Map.Entry<String, PackageParser.Provider> entry = i.next();
6581                 PackageParser.Provider p = entry.getValue();
6582                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6583
6584                 if (ps != null && p.syncable
6585                         && (!mSafeMode || (p.info.applicationInfo.flags
6586                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
6587                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
6588                             ps.readUserState(userId), userId);
6589                     if (info != null) {
6590                         outNames.add(entry.getKey());
6591                         outInfo.add(info);
6592                     }
6593                 }
6594             }
6595         }
6596     }
6597
6598     @Override
6599     public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
6600             int uid, int flags) {
6601         final int userId = processName != null ? UserHandle.getUserId(uid)
6602                 : UserHandle.getCallingUserId();
6603         if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6604         flags = updateFlagsForComponent(flags, userId, processName);
6605
6606         ArrayList<ProviderInfo> finalList = null;
6607         // reader
6608         synchronized (mPackages) {
6609             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
6610             while (i.hasNext()) {
6611                 final PackageParser.Provider p = i.next();
6612                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6613                 if (ps != null && p.info.authority != null
6614                         && (processName == null
6615                                 || (p.info.processName.equals(processName)
6616                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
6617                         && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
6618                     if (finalList == null) {
6619                         finalList = new ArrayList<ProviderInfo>(3);
6620                     }
6621                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
6622                             ps.readUserState(userId), userId);
6623                     if (info != null) {
6624                         finalList.add(info);
6625                     }
6626                 }
6627             }
6628         }
6629
6630         if (finalList != null) {
6631             Collections.sort(finalList, mProviderInitOrderSorter);
6632             return new ParceledListSlice<ProviderInfo>(finalList);
6633         }
6634
6635         return ParceledListSlice.emptyList();
6636     }
6637
6638     @Override
6639     public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6640         // reader
6641         synchronized (mPackages) {
6642             final PackageParser.Instrumentation i = mInstrumentation.get(name);
6643             return PackageParser.generateInstrumentationInfo(i, flags);
6644         }
6645     }
6646
6647     @Override
6648     public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
6649             String targetPackage, int flags) {
6650         return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
6651     }
6652
6653     private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
6654             int flags) {
6655         ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
6656
6657         // reader
6658         synchronized (mPackages) {
6659             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6660             while (i.hasNext()) {
6661                 final PackageParser.Instrumentation p = i.next();
6662                 if (targetPackage == null
6663                         || targetPackage.equals(p.info.targetPackage)) {
6664                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6665                             flags);
6666                     if (ii != null) {
6667                         finalList.add(ii);
6668                     }
6669                 }
6670             }
6671         }
6672
6673         return finalList;
6674     }
6675
6676     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6677         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6678         if (overlays == null) {
6679             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6680             return;
6681         }
6682         for (PackageParser.Package opkg : overlays.values()) {
6683             // Not much to do if idmap fails: we already logged the error
6684             // and we certainly don't want to abort installation of pkg simply
6685             // because an overlay didn't fit properly. For these reasons,
6686             // ignore the return value of createIdmapForPackagePairLI.
6687             createIdmapForPackagePairLI(pkg, opkg);
6688         }
6689     }
6690
6691     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6692             PackageParser.Package opkg) {
6693         if (!opkg.mTrustedOverlay) {
6694             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6695                     opkg.baseCodePath + ": overlay not trusted");
6696             return false;
6697         }
6698         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6699         if (overlaySet == null) {
6700             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6701                     opkg.baseCodePath + " but target package has no known overlays");
6702             return false;
6703         }
6704         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6705         // TODO: generate idmap for split APKs
6706         try {
6707             mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
6708         } catch (InstallerException e) {
6709             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6710                     + opkg.baseCodePath);
6711             return false;
6712         }
6713         PackageParser.Package[] overlayArray =
6714             overlaySet.values().toArray(new PackageParser.Package[0]);
6715         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6716             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6717                 return p1.mOverlayPriority - p2.mOverlayPriority;
6718             }
6719         };
6720         Arrays.sort(overlayArray, cmp);
6721
6722         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6723         int i = 0;
6724         for (PackageParser.Package p : overlayArray) {
6725             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6726         }
6727         return true;
6728     }
6729
6730     private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6731         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6732         try {
6733             scanDirLI(dir, parseFlags, scanFlags, currentTime);
6734         } finally {
6735             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6736         }
6737     }
6738
6739     private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6740         final File[] files = dir.listFiles();
6741         if (ArrayUtils.isEmpty(files)) {
6742             Log.d(TAG, "No files in app dir " + dir);
6743             return;
6744         }
6745
6746         if (DEBUG_PACKAGE_SCANNING) {
6747             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6748                     + " flags=0x" + Integer.toHexString(parseFlags));
6749         }
6750
6751         for (File file : files) {
6752             final boolean isPackage = (isApkFile(file) || file.isDirectory())
6753                     && !PackageInstallerService.isStageName(file.getName());
6754             if (!isPackage) {
6755                 // Ignore entries which are not packages
6756                 continue;
6757             }
6758             try {
6759                 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6760                         scanFlags, currentTime, null);
6761             } catch (PackageManagerException e) {
6762                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6763
6764                 // Delete invalid userdata apps
6765                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6766                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6767                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6768                     removeCodePathLI(file);
6769                 }
6770             }
6771         }
6772     }
6773
6774     private static File getSettingsProblemFile() {
6775         File dataDir = Environment.getDataDirectory();
6776         File systemDir = new File(dataDir, "system");
6777         File fname = new File(systemDir, "uiderrors.txt");
6778         return fname;
6779     }
6780
6781     static void reportSettingsProblem(int priority, String msg) {
6782         logCriticalInfo(priority, msg);
6783     }
6784
6785     static void logCriticalInfo(int priority, String msg) {
6786         Slog.println(priority, TAG, msg);
6787         EventLogTags.writePmCriticalInfo(msg);
6788         try {
6789             File fname = getSettingsProblemFile();
6790             FileOutputStream out = new FileOutputStream(fname, true);
6791             PrintWriter pw = new FastPrintWriter(out);
6792             SimpleDateFormat formatter = new SimpleDateFormat();
6793             String dateString = formatter.format(new Date(System.currentTimeMillis()));
6794             pw.println(dateString + ": " + msg);
6795             pw.close();
6796             FileUtils.setPermissions(
6797                     fname.toString(),
6798                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6799                     -1, -1);
6800         } catch (java.io.IOException e) {
6801         }
6802     }
6803
6804     private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
6805         if (srcFile.isDirectory()) {
6806             final File baseFile = new File(pkg.baseCodePath);
6807             long maxModifiedTime = baseFile.lastModified();
6808             if (pkg.splitCodePaths != null) {
6809                 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
6810                     final File splitFile = new File(pkg.splitCodePaths[i]);
6811                     maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
6812                 }
6813             }
6814             return maxModifiedTime;
6815         }
6816         return srcFile.lastModified();
6817     }
6818
6819     private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
6820             final int policyFlags) throws PackageManagerException {
6821         // When upgrading from pre-N MR1, verify the package time stamp using the package
6822         // directory and not the APK file.
6823         final long lastModifiedTime = mIsPreNMR1Upgrade
6824                 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
6825         if (ps != null
6826                 && ps.codePath.equals(srcFile)
6827                 && ps.timeStamp == lastModifiedTime
6828                 && !isCompatSignatureUpdateNeeded(pkg)
6829                 && !isRecoverSignatureUpdateNeeded(pkg)) {
6830             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6831             KeySetManagerService ksms = mSettings.mKeySetManagerService;
6832             ArraySet<PublicKey> signingKs;
6833             synchronized (mPackages) {
6834                 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6835             }
6836             if (ps.signatures.mSignatures != null
6837                     && ps.signatures.mSignatures.length != 0
6838                     && signingKs != null) {
6839                 // Optimization: reuse the existing cached certificates
6840                 // if the package appears to be unchanged.
6841                 pkg.mSignatures = ps.signatures.mSignatures;
6842                 pkg.mSigningKeys = signingKs;
6843                 return;
6844             }
6845
6846             Slog.w(TAG, "PackageSetting for " + ps.name
6847                     + " is missing signatures.  Collecting certs again to recover them.");
6848         } else {
6849             Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
6850         }
6851
6852         try {
6853             PackageParser.collectCertificates(pkg, policyFlags);
6854         } catch (PackageParserException e) {
6855             throw PackageManagerException.from(e);
6856         }
6857     }
6858
6859     /**
6860      *  Traces a package scan.
6861      *  @see #scanPackageLI(File, int, int, long, UserHandle)
6862      */
6863     private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
6864             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6865         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6866         try {
6867             return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6868         } finally {
6869             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6870         }
6871     }
6872
6873     /**
6874      *  Scans a package and returns the newly parsed package.
6875      *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6876      */
6877     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6878             long currentTime, UserHandle user) throws PackageManagerException {
6879         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6880         PackageParser pp = new PackageParser();
6881         pp.setSeparateProcesses(mSeparateProcesses);
6882         pp.setOnlyCoreApps(mOnlyCore);
6883         pp.setDisplayMetrics(mMetrics);
6884
6885         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6886             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6887         }
6888
6889         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
6890         final PackageParser.Package pkg;
6891         try {
6892             pkg = pp.parsePackage(scanFile, parseFlags);
6893         } catch (PackageParserException e) {
6894             throw PackageManagerException.from(e);
6895         } finally {
6896             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6897         }
6898
6899         return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
6900     }
6901
6902     /**
6903      *  Scans a package and returns the newly parsed package.
6904      *  @throws PackageManagerException on a parse error.
6905      */
6906     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
6907             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
6908             throws PackageManagerException {
6909         // If the package has children and this is the first dive in the function
6910         // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
6911         // packages (parent and children) would be successfully scanned before the
6912         // actual scan since scanning mutates internal state and we want to atomically
6913         // install the package and its children.
6914         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
6915             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
6916                 scanFlags |= SCAN_CHECK_ONLY;
6917             }
6918         } else {
6919             scanFlags &= ~SCAN_CHECK_ONLY;
6920         }
6921
6922         // Scan the parent
6923         PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
6924                 scanFlags, currentTime, user);
6925
6926         // Scan the children
6927         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
6928         for (int i = 0; i < childCount; i++) {
6929             PackageParser.Package childPackage = pkg.childPackages.get(i);
6930             scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
6931                     currentTime, user);
6932         }
6933
6934
6935         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
6936             return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
6937         }
6938
6939         return scannedPkg;
6940     }
6941
6942     /**
6943      *  Scans a package and returns the newly parsed package.
6944      *  @throws PackageManagerException on a parse error.
6945      */
6946     private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
6947             int policyFlags, int scanFlags, long currentTime, UserHandle user)
6948             throws PackageManagerException {
6949         PackageSetting ps = null;
6950         PackageSetting updatedPkg;
6951         // reader
6952         synchronized (mPackages) {
6953             // Look to see if we already know about this package.
6954             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6955             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6956                 // This package has been renamed to its original name.  Let's
6957                 // use that.
6958                 ps = mSettings.peekPackageLPr(oldName);
6959             }
6960             // If there was no original package, see one for the real package name.
6961             if (ps == null) {
6962                 ps = mSettings.peekPackageLPr(pkg.packageName);
6963             }
6964             // Check to see if this package could be hiding/updating a system
6965             // package.  Must look for it either under the original or real
6966             // package name depending on our state.
6967             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6968             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6969
6970             // If this is a package we don't know about on the system partition, we
6971             // may need to remove disabled child packages on the system partition
6972             // or may need to not add child packages if the parent apk is updated
6973             // on the data partition and no longer defines this child package.
6974             if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6975                 // If this is a parent package for an updated system app and this system
6976                 // app got an OTA update which no longer defines some of the child packages
6977                 // we have to prune them from the disabled system packages.
6978                 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
6979                 if (disabledPs != null) {
6980                     final int scannedChildCount = (pkg.childPackages != null)
6981                             ? pkg.childPackages.size() : 0;
6982                     final int disabledChildCount = disabledPs.childPackageNames != null
6983                             ? disabledPs.childPackageNames.size() : 0;
6984                     for (int i = 0; i < disabledChildCount; i++) {
6985                         String disabledChildPackageName = disabledPs.childPackageNames.get(i);
6986                         boolean disabledPackageAvailable = false;
6987                         for (int j = 0; j < scannedChildCount; j++) {
6988                             PackageParser.Package childPkg = pkg.childPackages.get(j);
6989                             if (childPkg.packageName.equals(disabledChildPackageName)) {
6990                                 disabledPackageAvailable = true;
6991                                 break;
6992                             }
6993                          }
6994                          if (!disabledPackageAvailable) {
6995                              mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
6996                          }
6997                     }
6998                 }
6999             }
7000         }
7001
7002         boolean updatedPkgBetter = false;
7003         // First check if this is a system package that may involve an update
7004         if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
7005             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
7006             // it needs to drop FLAG_PRIVILEGED.
7007             if (locationIsPrivileged(scanFile)) {
7008                 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7009             } else {
7010                 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7011             }
7012
7013             if (ps != null && !ps.codePath.equals(scanFile)) {
7014                 // The path has changed from what was last scanned...  check the
7015                 // version of the new path against what we have stored to determine
7016                 // what to do.
7017                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
7018                 if (pkg.mVersionCode <= ps.versionCode) {
7019                     // The system package has been updated and the code path does not match
7020                     // Ignore entry. Skip it.
7021                     if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
7022                             + " ignored: updated version " + ps.versionCode
7023                             + " better than this " + pkg.mVersionCode);
7024                     if (!updatedPkg.codePath.equals(scanFile)) {
7025                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
7026                                 + ps.name + " changing from " + updatedPkg.codePathString
7027                                 + " to " + scanFile);
7028                         updatedPkg.codePath = scanFile;
7029                         updatedPkg.codePathString = scanFile.toString();
7030                         updatedPkg.resourcePath = scanFile;
7031                         updatedPkg.resourcePathString = scanFile.toString();
7032                     }
7033                     updatedPkg.pkg = pkg;
7034                     updatedPkg.versionCode = pkg.mVersionCode;
7035
7036                     // Update the disabled system child packages to point to the package too.
7037                     final int childCount = updatedPkg.childPackageNames != null
7038                             ? updatedPkg.childPackageNames.size() : 0;
7039                     for (int i = 0; i < childCount; i++) {
7040                         String childPackageName = updatedPkg.childPackageNames.get(i);
7041                         PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
7042                                 childPackageName);
7043                         if (updatedChildPkg != null) {
7044                             updatedChildPkg.pkg = pkg;
7045                             updatedChildPkg.versionCode = pkg.mVersionCode;
7046                         }
7047                     }
7048
7049                     throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
7050                             + scanFile + " ignored: updated version " + ps.versionCode
7051                             + " better than this " + pkg.mVersionCode);
7052                 } else {
7053                     // The current app on the system partition is better than
7054                     // what we have updated to on the data partition; switch
7055                     // back to the system partition version.
7056                     // At this point, its safely assumed that package installation for
7057                     // apps in system partition will go through. If not there won't be a working
7058                     // version of the app
7059                     // writer
7060                     synchronized (mPackages) {
7061                         // Just remove the loaded entries from package lists.
7062                         mPackages.remove(ps.name);
7063                     }
7064
7065                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7066                             + " reverting from " + ps.codePathString
7067                             + ": new version " + pkg.mVersionCode
7068                             + " better than installed " + ps.versionCode);
7069
7070                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7071                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7072                     synchronized (mInstallLock) {
7073                         args.cleanUpResourcesLI();
7074                     }
7075                     synchronized (mPackages) {
7076                         mSettings.enableSystemPackageLPw(ps.name);
7077                     }
7078                     updatedPkgBetter = true;
7079                 }
7080             }
7081         }
7082
7083         if (updatedPkg != null) {
7084             // An updated system app will not have the PARSE_IS_SYSTEM flag set
7085             // initially
7086             policyFlags |= PackageParser.PARSE_IS_SYSTEM;
7087
7088             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
7089             // flag set initially
7090             if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
7091                 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
7092             }
7093         }
7094
7095         // Verify certificates against what was last scanned
7096         collectCertificatesLI(ps, pkg, scanFile, policyFlags);
7097
7098         /*
7099          * A new system app appeared, but we already had a non-system one of the
7100          * same name installed earlier.
7101          */
7102         boolean shouldHideSystemApp = false;
7103         if (updatedPkg == null && ps != null
7104                 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
7105             /*
7106              * Check to make sure the signatures match first. If they don't,
7107              * wipe the installed application and its data.
7108              */
7109             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
7110                     != PackageManager.SIGNATURE_MATCH) {
7111                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
7112                         + " signatures don't match existing userdata copy; removing");
7113                 try (PackageFreezer freezer = freezePackage(pkg.packageName,
7114                         "scanPackageInternalLI")) {
7115                     deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
7116                 }
7117                 ps = null;
7118             } else {
7119                 /*
7120                  * If the newly-added system app is an older version than the
7121                  * already installed version, hide it. It will be scanned later
7122                  * and re-added like an update.
7123                  */
7124                 if (pkg.mVersionCode <= ps.versionCode) {
7125                     shouldHideSystemApp = true;
7126                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
7127                             + " but new version " + pkg.mVersionCode + " better than installed "
7128                             + ps.versionCode + "; hiding system");
7129                 } else {
7130                     /*
7131                      * The newly found system app is a newer version that the
7132                      * one previously installed. Simply remove the
7133                      * already-installed application and replace it with our own
7134                      * while keeping the application data.
7135                      */
7136                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7137                             + " reverting from " + ps.codePathString + ": new version "
7138                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
7139                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7140                             ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7141                     synchronized (mInstallLock) {
7142                         args.cleanUpResourcesLI();
7143                     }
7144                 }
7145             }
7146         }
7147
7148         // The apk is forward locked (not public) if its code and resources
7149         // are kept in different files. (except for app in either system or
7150         // vendor path).
7151         // TODO grab this value from PackageSettings
7152         if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7153             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
7154                 policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
7155             }
7156         }
7157
7158         // TODO: extend to support forward-locked splits
7159         String resourcePath = null;
7160         String baseResourcePath = null;
7161         if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
7162             if (ps != null && ps.resourcePathString != null) {
7163                 resourcePath = ps.resourcePathString;
7164                 baseResourcePath = ps.resourcePathString;
7165             } else {
7166                 // Should not happen at all. Just log an error.
7167                 Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
7168             }
7169         } else {
7170             resourcePath = pkg.codePath;
7171             baseResourcePath = pkg.baseCodePath;
7172         }
7173
7174         // Set application objects path explicitly.
7175         pkg.setApplicationVolumeUuid(pkg.volumeUuid);
7176         pkg.setApplicationInfoCodePath(pkg.codePath);
7177         pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
7178         pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
7179         pkg.setApplicationInfoResourcePath(resourcePath);
7180         pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
7181         pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
7182
7183         // Note that we invoke the following method only if we are about to unpack an application
7184         PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
7185                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
7186
7187         /*
7188          * If the system app should be overridden by a previously installed
7189          * data, hide the system app now and let the /data/app scan pick it up
7190          * again.
7191          */
7192         if (shouldHideSystemApp) {
7193             synchronized (mPackages) {
7194                 mSettings.disableSystemPackageLPw(pkg.packageName, true);
7195             }
7196         }
7197
7198         return scannedPkg;
7199     }
7200
7201     private static String fixProcessName(String defProcessName,
7202             String processName, int uid) {
7203         if (processName == null) {
7204             return defProcessName;
7205         }
7206         return processName;
7207     }
7208
7209     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
7210             throws PackageManagerException {
7211         if (pkgSetting.signatures.mSignatures != null) {
7212             // Already existing package. Make sure signatures match
7213             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
7214                     == PackageManager.SIGNATURE_MATCH;
7215             if (!match) {
7216                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
7217                         == PackageManager.SIGNATURE_MATCH;
7218             }
7219             if (!match) {
7220                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
7221                         == PackageManager.SIGNATURE_MATCH;
7222             }
7223             if (!match) {
7224                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
7225                         + pkg.packageName + " signatures do not match the "
7226                         + "previously installed version; ignoring!");
7227             }
7228         }
7229
7230         // Check for shared user signatures
7231         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
7232             // Already existing package. Make sure signatures match
7233             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7234                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
7235             if (!match) {
7236                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
7237                         == PackageManager.SIGNATURE_MATCH;
7238             }
7239             if (!match) {
7240                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
7241                         == PackageManager.SIGNATURE_MATCH;
7242             }
7243             if (!match) {
7244                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
7245                         "Package " + pkg.packageName
7246                         + " has no signatures that match those in shared user "
7247                         + pkgSetting.sharedUser.name + "; ignoring!");
7248             }
7249         }
7250     }
7251
7252     /**
7253      * Enforces that only the system UID or root's UID can call a method exposed
7254      * via Binder.
7255      *
7256      * @param message used as message if SecurityException is thrown
7257      * @throws SecurityException if the caller is not system or root
7258      */
7259     private static final void enforceSystemOrRoot(String message) {
7260         final int uid = Binder.getCallingUid();
7261         if (uid != Process.SYSTEM_UID && uid != 0) {
7262             throw new SecurityException(message);
7263         }
7264     }
7265
7266     @Override
7267     public void performFstrimIfNeeded() {
7268         enforceSystemOrRoot("Only the system can request fstrim");
7269
7270         // Before everything else, see whether we need to fstrim.
7271         try {
7272             IMountService ms = PackageHelper.getMountService();
7273             if (ms != null) {
7274                 boolean doTrim = false;
7275                 final long interval = android.provider.Settings.Global.getLong(
7276                         mContext.getContentResolver(),
7277                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
7278                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
7279                 if (interval > 0) {
7280                     final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
7281                     if (timeSinceLast > interval) {
7282                         doTrim = true;
7283                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
7284                                 + "; running immediately");
7285                     }
7286                 }
7287                 if (doTrim) {
7288                     final boolean dexOptDialogShown;
7289                     synchronized (mPackages) {
7290                         dexOptDialogShown = mDexOptDialogShown;
7291                     }
7292                     if (!isFirstBoot() && dexOptDialogShown) {
7293                         try {
7294                             ActivityManagerNative.getDefault().showBootMessage(
7295                                     mContext.getResources().getString(
7296                                             R.string.android_upgrading_fstrim), true);
7297                         } catch (RemoteException e) {
7298                         }
7299                     }
7300                     ms.runMaintenance();
7301                 }
7302             } else {
7303                 Slog.e(TAG, "Mount service unavailable!");
7304             }
7305         } catch (RemoteException e) {
7306             // Can't happen; MountService is local
7307         }
7308     }
7309
7310     @Override
7311     public void updatePackagesIfNeeded() {
7312         enforceSystemOrRoot("Only the system can request package update");
7313
7314         // We need to re-extract after an OTA.
7315         boolean causeUpgrade = isUpgrade();
7316
7317         // First boot or factory reset.
7318         // Note: we also handle devices that are upgrading to N right now as if it is their
7319         //       first boot, as they do not have profile data.
7320         boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
7321
7322         // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
7323         boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
7324
7325         if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
7326             return;
7327         }
7328
7329         List<PackageParser.Package> pkgs;
7330         synchronized (mPackages) {
7331             pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
7332         }
7333
7334         final long startTime = System.nanoTime();
7335         final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
7336                     getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
7337
7338         final int elapsedTimeSeconds =
7339                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
7340
7341         MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
7342         MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
7343         MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
7344         MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
7345         MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
7346     }
7347
7348     /**
7349      * Performs dexopt on the set of packages in {@code packages} and returns an int array
7350      * containing statistics about the invocation. The array consists of three elements,
7351      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
7352      * and {@code numberOfPackagesFailed}.
7353      */
7354     private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
7355             String compilerFilter) {
7356
7357         int numberOfPackagesVisited = 0;
7358         int numberOfPackagesOptimized = 0;
7359         int numberOfPackagesSkipped = 0;
7360         int numberOfPackagesFailed = 0;
7361         final int numberOfPackagesToDexopt = pkgs.size();
7362
7363         for (PackageParser.Package pkg : pkgs) {
7364             numberOfPackagesVisited++;
7365
7366             if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
7367                 if (DEBUG_DEXOPT) {
7368                     Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
7369                 }
7370                 numberOfPackagesSkipped++;
7371                 continue;
7372             }
7373
7374             if (DEBUG_DEXOPT) {
7375                 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
7376                         numberOfPackagesToDexopt + ": " + pkg.packageName);
7377             }
7378
7379             if (showDialog) {
7380                 try {
7381                     ActivityManagerNative.getDefault().showBootMessage(
7382                             mContext.getResources().getString(R.string.android_upgrading_apk,
7383                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
7384                 } catch (RemoteException e) {
7385                 }
7386                 synchronized (mPackages) {
7387                     mDexOptDialogShown = true;
7388                 }
7389             }
7390
7391             // If the OTA updates a system app which was previously preopted to a non-preopted state
7392             // the app might end up being verified at runtime. That's because by default the apps
7393             // are verify-profile but for preopted apps there's no profile.
7394             // Do a hacky check to ensure that if we have no profiles (a reasonable indication
7395             // that before the OTA the app was preopted) the app gets compiled with a non-profile
7396             // filter (by default interpret-only).
7397             // Note that at this stage unused apps are already filtered.
7398             if (isSystemApp(pkg) &&
7399                     DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
7400                     !Environment.getReferenceProfile(pkg.packageName).exists()) {
7401                 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
7402             }
7403
7404             // checkProfiles is false to avoid merging profiles during boot which
7405             // might interfere with background compilation (b/28612421).
7406             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
7407             // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
7408             // trade-off worth doing to save boot time work.
7409             int dexOptStatus = performDexOptTraced(pkg.packageName,
7410                     false /* checkProfiles */,
7411                     compilerFilter,
7412                     false /* force */);
7413             switch (dexOptStatus) {
7414                 case PackageDexOptimizer.DEX_OPT_PERFORMED:
7415                     numberOfPackagesOptimized++;
7416                     break;
7417                 case PackageDexOptimizer.DEX_OPT_SKIPPED:
7418                     numberOfPackagesSkipped++;
7419                     break;
7420                 case PackageDexOptimizer.DEX_OPT_FAILED:
7421                     numberOfPackagesFailed++;
7422                     break;
7423                 default:
7424                     Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
7425                     break;
7426             }
7427         }
7428
7429         return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
7430                 numberOfPackagesFailed };
7431     }
7432
7433     @Override
7434     public void notifyPackageUse(String packageName, int reason) {
7435         synchronized (mPackages) {
7436             PackageParser.Package p = mPackages.get(packageName);
7437             if (p == null) {
7438                 return;
7439             }
7440             p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
7441         }
7442     }
7443
7444     // TODO: this is not used nor needed. Delete it.
7445     @Override
7446     public boolean performDexOptIfNeeded(String packageName) {
7447         int dexOptStatus = performDexOptTraced(packageName,
7448                 false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
7449         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7450     }
7451
7452     @Override
7453     public boolean performDexOpt(String packageName,
7454             boolean checkProfiles, int compileReason, boolean force) {
7455         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7456                 getCompilerFilterForReason(compileReason), force);
7457         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7458     }
7459
7460     @Override
7461     public boolean performDexOptMode(String packageName,
7462             boolean checkProfiles, String targetCompilerFilter, boolean force) {
7463         int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7464                 targetCompilerFilter, force);
7465         return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7466     }
7467
7468     private int performDexOptTraced(String packageName,
7469                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
7470         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7471         try {
7472             return performDexOptInternal(packageName, checkProfiles,
7473                     targetCompilerFilter, force);
7474         } finally {
7475             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7476         }
7477     }
7478
7479     // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
7480     // if the package can now be considered up to date for the given filter.
7481     private int performDexOptInternal(String packageName,
7482                 boolean checkProfiles, String targetCompilerFilter, boolean force) {
7483         PackageParser.Package p;
7484         synchronized (mPackages) {
7485             p = mPackages.get(packageName);
7486             if (p == null) {
7487                 // Package could not be found. Report failure.
7488                 return PackageDexOptimizer.DEX_OPT_FAILED;
7489             }
7490             mPackageUsage.maybeWriteAsync(mPackages);
7491             mCompilerStats.maybeWriteAsync();
7492         }
7493         long callingId = Binder.clearCallingIdentity();
7494         try {
7495             synchronized (mInstallLock) {
7496                 return performDexOptInternalWithDependenciesLI(p, checkProfiles,
7497                         targetCompilerFilter, force);
7498             }
7499         } finally {
7500             Binder.restoreCallingIdentity(callingId);
7501         }
7502     }
7503
7504     public ArraySet<String> getOptimizablePackages() {
7505         ArraySet<String> pkgs = new ArraySet<String>();
7506         synchronized (mPackages) {
7507             for (PackageParser.Package p : mPackages.values()) {
7508                 if (PackageDexOptimizer.canOptimizePackage(p)) {
7509                     pkgs.add(p.packageName);
7510                 }
7511             }
7512         }
7513         return pkgs;
7514     }
7515
7516     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
7517             boolean checkProfiles, String targetCompilerFilter,
7518             boolean force) {
7519         // Select the dex optimizer based on the force parameter.
7520         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
7521         //       allocate an object here.
7522         PackageDexOptimizer pdo = force
7523                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
7524                 : mPackageDexOptimizer;
7525
7526         // Optimize all dependencies first. Note: we ignore the return value and march on
7527         // on errors.
7528         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
7529         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
7530         if (!deps.isEmpty()) {
7531             for (PackageParser.Package depPackage : deps) {
7532                 // TODO: Analyze and investigate if we (should) profile libraries.
7533                 // Currently this will do a full compilation of the library by default.
7534                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
7535                         false /* checkProfiles */,
7536                         getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
7537                         getOrCreateCompilerPackageStats(depPackage));
7538             }
7539         }
7540         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
7541                 targetCompilerFilter, getOrCreateCompilerPackageStats(p));
7542     }
7543
7544     Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
7545         if (p.usesLibraries != null || p.usesOptionalLibraries != null) {
7546             ArrayList<PackageParser.Package> retValue = new ArrayList<>();
7547             Set<String> collectedNames = new HashSet<>();
7548             findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
7549
7550             retValue.remove(p);
7551
7552             return retValue;
7553         } else {
7554             return Collections.emptyList();
7555         }
7556     }
7557
7558     private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
7559             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7560         if (!collectedNames.contains(p.packageName)) {
7561             collectedNames.add(p.packageName);
7562             collected.add(p);
7563
7564             if (p.usesLibraries != null) {
7565                 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames);
7566             }
7567             if (p.usesOptionalLibraries != null) {
7568                 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected,
7569                         collectedNames);
7570             }
7571         }
7572     }
7573
7574     private void findSharedNonSystemLibrariesRecursive(Collection<String> libs,
7575             Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7576         for (String libName : libs) {
7577             PackageParser.Package libPkg = findSharedNonSystemLibrary(libName);
7578             if (libPkg != null) {
7579                 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
7580             }
7581         }
7582     }
7583
7584     private PackageParser.Package findSharedNonSystemLibrary(String libName) {
7585         synchronized (mPackages) {
7586             PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
7587             if (lib != null && lib.apk != null) {
7588                 return mPackages.get(lib.apk);
7589             }
7590         }
7591         return null;
7592     }
7593
7594     public void shutdown() {
7595         mPackageUsage.writeNow(mPackages);
7596         mCompilerStats.writeNow();
7597     }
7598
7599     @Override
7600     public void dumpProfiles(String packageName) {
7601         PackageParser.Package pkg;
7602         synchronized (mPackages) {
7603             pkg = mPackages.get(packageName);
7604             if (pkg == null) {
7605                 throw new IllegalArgumentException("Unknown package: " + packageName);
7606             }
7607         }
7608         /* Only the shell, root, or the app user should be able to dump profiles. */
7609         int callingUid = Binder.getCallingUid();
7610         if (callingUid != Process.SHELL_UID &&
7611             callingUid != Process.ROOT_UID &&
7612             callingUid != pkg.applicationInfo.uid) {
7613             throw new SecurityException("dumpProfiles");
7614         }
7615
7616         synchronized (mInstallLock) {
7617             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
7618             final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
7619             try {
7620                 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
7621                 String gid = Integer.toString(sharedGid);
7622                 String codePaths = TextUtils.join(";", allCodePaths);
7623                 mInstaller.dumpProfiles(gid, packageName, codePaths);
7624             } catch (InstallerException e) {
7625                 Slog.w(TAG, "Failed to dump profiles", e);
7626             }
7627             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7628         }
7629     }
7630
7631     @Override
7632     public void forceDexOpt(String packageName) {
7633         enforceSystemOrRoot("forceDexOpt");
7634
7635         PackageParser.Package pkg;
7636         synchronized (mPackages) {
7637             pkg = mPackages.get(packageName);
7638             if (pkg == null) {
7639                 throw new IllegalArgumentException("Unknown package: " + packageName);
7640             }
7641         }
7642
7643         synchronized (mInstallLock) {
7644             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7645
7646             // Whoever is calling forceDexOpt wants a fully compiled package.
7647             // Don't use profiles since that may cause compilation to be skipped.
7648             final int res = performDexOptInternalWithDependenciesLI(pkg,
7649                     false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
7650                     true /* force */);
7651
7652             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7653             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
7654                 throw new IllegalStateException("Failed to dexopt: " + res);
7655             }
7656         }
7657     }
7658
7659     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
7660         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7661             Slog.w(TAG, "Unable to update from " + oldPkg.name
7662                     + " to " + newPkg.packageName
7663                     + ": old package not in system partition");
7664             return false;
7665         } else if (mPackages.get(oldPkg.name) != null) {
7666             Slog.w(TAG, "Unable to update from " + oldPkg.name
7667                     + " to " + newPkg.packageName
7668                     + ": old package still exists");
7669             return false;
7670         }
7671         return true;
7672     }
7673
7674     void removeCodePathLI(File codePath) {
7675         if (codePath.isDirectory()) {
7676             try {
7677                 mInstaller.rmPackageDir(codePath.getAbsolutePath());
7678             } catch (InstallerException e) {
7679                 Slog.w(TAG, "Failed to remove code path", e);
7680             }
7681         } else {
7682             codePath.delete();
7683         }
7684     }
7685
7686     private int[] resolveUserIds(int userId) {
7687         return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
7688     }
7689
7690     private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7691         if (pkg == null) {
7692             Slog.wtf(TAG, "Package was null!", new Throwable());
7693             return;
7694         }
7695         clearAppDataLeafLIF(pkg, userId, flags);
7696         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7697         for (int i = 0; i < childCount; i++) {
7698             clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7699         }
7700     }
7701
7702     private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7703         final PackageSetting ps;
7704         synchronized (mPackages) {
7705             ps = mSettings.mPackages.get(pkg.packageName);
7706         }
7707         for (int realUserId : resolveUserIds(userId)) {
7708             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7709             try {
7710                 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7711                         ceDataInode);
7712             } catch (InstallerException e) {
7713                 Slog.w(TAG, String.valueOf(e));
7714             }
7715         }
7716     }
7717
7718     private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7719         if (pkg == null) {
7720             Slog.wtf(TAG, "Package was null!", new Throwable());
7721             return;
7722         }
7723         destroyAppDataLeafLIF(pkg, userId, flags);
7724         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7725         for (int i = 0; i < childCount; i++) {
7726             destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7727         }
7728     }
7729
7730     private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7731         final PackageSetting ps;
7732         synchronized (mPackages) {
7733             ps = mSettings.mPackages.get(pkg.packageName);
7734         }
7735         for (int realUserId : resolveUserIds(userId)) {
7736             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7737             try {
7738                 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7739                         ceDataInode);
7740             } catch (InstallerException e) {
7741                 Slog.w(TAG, String.valueOf(e));
7742             }
7743         }
7744     }
7745
7746     private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
7747         if (pkg == null) {
7748             Slog.wtf(TAG, "Package was null!", new Throwable());
7749             return;
7750         }
7751         destroyAppProfilesLeafLIF(pkg);
7752         destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */);
7753         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7754         for (int i = 0; i < childCount; i++) {
7755             destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
7756             destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId,
7757                     true /* removeBaseMarker */);
7758         }
7759     }
7760
7761     private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId,
7762             boolean removeBaseMarker) {
7763         if (pkg.isForwardLocked()) {
7764             return;
7765         }
7766
7767         for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
7768             try {
7769                 path = PackageManagerServiceUtils.realpath(new File(path));
7770             } catch (IOException e) {
7771                 // TODO: Should we return early here ?
7772                 Slog.w(TAG, "Failed to get canonical path", e);
7773                 continue;
7774             }
7775
7776             final String useMarker = path.replace('/', '@');
7777             for (int realUserId : resolveUserIds(userId)) {
7778                 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId);
7779                 if (removeBaseMarker) {
7780                     File foreignUseMark = new File(profileDir, useMarker);
7781                     if (foreignUseMark.exists()) {
7782                         if (!foreignUseMark.delete()) {
7783                             Slog.w(TAG, "Unable to delete foreign user mark for package: "
7784                                     + pkg.packageName);
7785                         }
7786                     }
7787                 }
7788
7789                 File[] markers = profileDir.listFiles();
7790                 if (markers != null) {
7791                     final String searchString = "@" + pkg.packageName + "@";
7792                     // We also delete all markers that contain the package name we're
7793                     // uninstalling. These are associated with secondary dex-files belonging
7794                     // to the package. Reconstructing the path of these dex files is messy
7795                     // in general.
7796                     for (File marker : markers) {
7797                         if (marker.getName().indexOf(searchString) > 0) {
7798                             if (!marker.delete()) {
7799                                 Slog.w(TAG, "Unable to delete foreign user mark for package: "
7800                                     + pkg.packageName);
7801                             }
7802                         }
7803                     }
7804                 }
7805             }
7806         }
7807     }
7808
7809     private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
7810         try {
7811             mInstaller.destroyAppProfiles(pkg.packageName);
7812         } catch (InstallerException e) {
7813             Slog.w(TAG, String.valueOf(e));
7814         }
7815     }
7816
7817     private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
7818         if (pkg == null) {
7819             Slog.wtf(TAG, "Package was null!", new Throwable());
7820             return;
7821         }
7822         clearAppProfilesLeafLIF(pkg);
7823         // We don't remove the base foreign use marker when clearing profiles because
7824         // we will rename it when the app is updated. Unlike the actual profile contents,
7825         // the foreign use marker is good across installs.
7826         destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */);
7827         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7828         for (int i = 0; i < childCount; i++) {
7829             clearAppProfilesLeafLIF(pkg.childPackages.get(i));
7830         }
7831     }
7832
7833     private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
7834         try {
7835             mInstaller.clearAppProfiles(pkg.packageName);
7836         } catch (InstallerException e) {
7837             Slog.w(TAG, String.valueOf(e));
7838         }
7839     }
7840
7841     private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
7842             long lastUpdateTime) {
7843         // Set parent install/update time
7844         PackageSetting ps = (PackageSetting) pkg.mExtras;
7845         if (ps != null) {
7846             ps.firstInstallTime = firstInstallTime;
7847             ps.lastUpdateTime = lastUpdateTime;
7848         }
7849         // Set children install/update time
7850         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7851         for (int i = 0; i < childCount; i++) {
7852             PackageParser.Package childPkg = pkg.childPackages.get(i);
7853             ps = (PackageSetting) childPkg.mExtras;
7854             if (ps != null) {
7855                 ps.firstInstallTime = firstInstallTime;
7856                 ps.lastUpdateTime = lastUpdateTime;
7857             }
7858         }
7859     }
7860
7861     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
7862             PackageParser.Package changingLib) {
7863         if (file.path != null) {
7864             usesLibraryFiles.add(file.path);
7865             return;
7866         }
7867         PackageParser.Package p = mPackages.get(file.apk);
7868         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
7869             // If we are doing this while in the middle of updating a library apk,
7870             // then we need to make sure to use that new apk for determining the
7871             // dependencies here.  (We haven't yet finished committing the new apk
7872             // to the package manager state.)
7873             if (p == null || p.packageName.equals(changingLib.packageName)) {
7874                 p = changingLib;
7875             }
7876         }
7877         if (p != null) {
7878             usesLibraryFiles.addAll(p.getAllCodePaths());
7879         }
7880     }
7881
7882     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
7883             PackageParser.Package changingLib) throws PackageManagerException {
7884         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
7885             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
7886             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
7887             for (int i=0; i<N; i++) {
7888                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
7889                 if (file == null) {
7890                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
7891                             "Package " + pkg.packageName + " requires unavailable shared library "
7892                             + pkg.usesLibraries.get(i) + "; failing!");
7893                 }
7894                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7895             }
7896             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
7897             for (int i=0; i<N; i++) {
7898                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
7899                 if (file == null) {
7900                     Slog.w(TAG, "Package " + pkg.packageName
7901                             + " desires unavailable shared library "
7902                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
7903                 } else {
7904                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7905                 }
7906             }
7907             N = usesLibraryFiles.size();
7908             if (N > 0) {
7909                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
7910             } else {
7911                 pkg.usesLibraryFiles = null;
7912             }
7913         }
7914     }
7915
7916     private static boolean hasString(List<String> list, List<String> which) {
7917         if (list == null) {
7918             return false;
7919         }
7920         for (int i=list.size()-1; i>=0; i--) {
7921             for (int j=which.size()-1; j>=0; j--) {
7922                 if (which.get(j).equals(list.get(i))) {
7923                     return true;
7924                 }
7925             }
7926         }
7927         return false;
7928     }
7929
7930     private void updateAllSharedLibrariesLPw() {
7931         for (PackageParser.Package pkg : mPackages.values()) {
7932             try {
7933                 updateSharedLibrariesLPw(pkg, null);
7934             } catch (PackageManagerException e) {
7935                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7936             }
7937         }
7938     }
7939
7940     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
7941             PackageParser.Package changingPkg) {
7942         ArrayList<PackageParser.Package> res = null;
7943         for (PackageParser.Package pkg : mPackages.values()) {
7944             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
7945                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
7946                 if (res == null) {
7947                     res = new ArrayList<PackageParser.Package>();
7948                 }
7949                 res.add(pkg);
7950                 try {
7951                     updateSharedLibrariesLPw(pkg, changingPkg);
7952                 } catch (PackageManagerException e) {
7953                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7954                 }
7955             }
7956         }
7957         return res;
7958     }
7959
7960     /**
7961      * Derive the value of the {@code cpuAbiOverride} based on the provided
7962      * value and an optional stored value from the package settings.
7963      */
7964     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
7965         String cpuAbiOverride = null;
7966
7967         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
7968             cpuAbiOverride = null;
7969         } else if (abiOverride != null) {
7970             cpuAbiOverride = abiOverride;
7971         } else if (settings != null) {
7972             cpuAbiOverride = settings.cpuAbiOverrideString;
7973         }
7974
7975         return cpuAbiOverride;
7976     }
7977
7978     private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
7979             final int policyFlags, int scanFlags, long currentTime, UserHandle user)
7980                     throws PackageManagerException {
7981         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
7982         // If the package has children and this is the first dive in the function
7983         // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
7984         // whether all packages (parent and children) would be successfully scanned
7985         // before the actual scan since scanning mutates internal state and we want
7986         // to atomically install the package and its children.
7987         if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7988             if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
7989                 scanFlags |= SCAN_CHECK_ONLY;
7990             }
7991         } else {
7992             scanFlags &= ~SCAN_CHECK_ONLY;
7993         }
7994
7995         final PackageParser.Package scannedPkg;
7996         try {
7997             // Scan the parent
7998             scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
7999             // Scan the children
8000             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8001             for (int i = 0; i < childCount; i++) {
8002                 PackageParser.Package childPkg = pkg.childPackages.get(i);
8003                 scanPackageLI(childPkg, policyFlags,
8004                         scanFlags, currentTime, user);
8005             }
8006         } finally {
8007             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8008         }
8009
8010         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8011             return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
8012         }
8013
8014         return scannedPkg;
8015     }
8016
8017     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
8018             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8019         boolean success = false;
8020         try {
8021             final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
8022                     currentTime, user);
8023             success = true;
8024             return res;
8025         } finally {
8026             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
8027                 // DELETE_DATA_ON_FAILURES is only used by frozen paths
8028                 destroyAppDataLIF(pkg, UserHandle.USER_ALL,
8029                         StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
8030                 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
8031             }
8032         }
8033     }
8034
8035     /**
8036      * Returns {@code true} if the given file contains code. Otherwise {@code false}.
8037      */
8038     private static boolean apkHasCode(String fileName) {
8039         StrictJarFile jarFile = null;
8040         try {
8041             jarFile = new StrictJarFile(fileName,
8042                     false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
8043             return jarFile.findEntry("classes.dex") != null;
8044         } catch (IOException ignore) {
8045         } finally {
8046             try {
8047                 if (jarFile != null) {
8048                     jarFile.close();
8049                 }
8050             } catch (IOException ignore) {}
8051         }
8052         return false;
8053     }
8054
8055     /**
8056      * Enforces code policy for the package. This ensures that if an APK has
8057      * declared hasCode="true" in its manifest that the APK actually contains
8058      * code.
8059      *
8060      * @throws PackageManagerException If bytecode could not be found when it should exist
8061      */
8062     private static void enforceCodePolicy(PackageParser.Package pkg)
8063             throws PackageManagerException {
8064         final boolean shouldHaveCode =
8065                 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
8066         if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
8067             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8068                     "Package " + pkg.baseCodePath + " code is missing");
8069         }
8070
8071         if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8072             for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8073                 final boolean splitShouldHaveCode =
8074                         (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
8075                 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
8076                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8077                             "Package " + pkg.splitCodePaths[i] + " code is missing");
8078                 }
8079             }
8080         }
8081     }
8082
8083     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
8084             final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
8085             throws PackageManagerException {
8086         final File scanFile = new File(pkg.codePath);
8087         if (pkg.applicationInfo.getCodePath() == null ||
8088                 pkg.applicationInfo.getResourcePath() == null) {
8089             // Bail out. The resource and code paths haven't been set.
8090             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8091                     "Code and resource paths haven't been set correctly");
8092         }
8093
8094         // Apply policy
8095         if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
8096             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
8097             if (pkg.applicationInfo.isDirectBootAware()) {
8098                 // we're direct boot aware; set for all components
8099                 for (PackageParser.Service s : pkg.services) {
8100                     s.info.encryptionAware = s.info.directBootAware = true;
8101                 }
8102                 for (PackageParser.Provider p : pkg.providers) {
8103                     p.info.encryptionAware = p.info.directBootAware = true;
8104                 }
8105                 for (PackageParser.Activity a : pkg.activities) {
8106                     a.info.encryptionAware = a.info.directBootAware = true;
8107                 }
8108                 for (PackageParser.Activity r : pkg.receivers) {
8109                     r.info.encryptionAware = r.info.directBootAware = true;
8110                 }
8111             }
8112         } else {
8113             // Only allow system apps to be flagged as core apps.
8114             pkg.coreApp = false;
8115             // clear flags not applicable to regular apps
8116             pkg.applicationInfo.privateFlags &=
8117                     ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
8118             pkg.applicationInfo.privateFlags &=
8119                     ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
8120         }
8121         pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
8122
8123         if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
8124             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8125         }
8126
8127         if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
8128             enforceCodePolicy(pkg);
8129         }
8130
8131         if (mCustomResolverComponentName != null &&
8132                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
8133             setUpCustomResolverActivity(pkg);
8134         }
8135
8136         if (pkg.packageName.equals("android")) {
8137             synchronized (mPackages) {
8138                 if (mAndroidApplication != null) {
8139                     Slog.w(TAG, "*************************************************");
8140                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
8141                     Slog.w(TAG, " file=" + scanFile);
8142                     Slog.w(TAG, "*************************************************");
8143                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
8144                             "Core android package being redefined.  Skipping.");
8145                 }
8146
8147                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8148                     // Set up information for our fall-back user intent resolution activity.
8149                     mPlatformPackage = pkg;
8150                     pkg.mVersionCode = mSdkVersion;
8151                     mAndroidApplication = pkg.applicationInfo;
8152
8153                     if (!mResolverReplaced) {
8154                         mResolveActivity.applicationInfo = mAndroidApplication;
8155                         mResolveActivity.name = ResolverActivity.class.getName();
8156                         mResolveActivity.packageName = mAndroidApplication.packageName;
8157                         mResolveActivity.processName = "system:ui";
8158                         mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8159                         mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
8160                         mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
8161                         mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
8162                         mResolveActivity.exported = true;
8163                         mResolveActivity.enabled = true;
8164                         mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
8165                         mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
8166                                 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
8167                                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
8168                                 | ActivityInfo.CONFIG_ORIENTATION
8169                                 | ActivityInfo.CONFIG_KEYBOARD
8170                                 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
8171                         mResolveInfo.activityInfo = mResolveActivity;
8172                         mResolveInfo.priority = 0;
8173                         mResolveInfo.preferredOrder = 0;
8174                         mResolveInfo.match = 0;
8175                         mResolveComponentName = new ComponentName(
8176                                 mAndroidApplication.packageName, mResolveActivity.name);
8177                     }
8178                 }
8179             }
8180         }
8181
8182         if (DEBUG_PACKAGE_SCANNING) {
8183             if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8184                 Log.d(TAG, "Scanning package " + pkg.packageName);
8185         }
8186
8187         final PackageParser.Package oldPkg;
8188
8189         synchronized (mPackages) {
8190             if (mPackages.containsKey(pkg.packageName)
8191                     || mSharedLibraries.containsKey(pkg.packageName)) {
8192                 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
8193                         "Application package " + pkg.packageName
8194                                 + " already installed.  Skipping duplicate.");
8195             }
8196
8197             final PackageSetting oldPkgSetting = mSettings.peekPackageLPr(pkg.packageName);
8198             if (oldPkgSetting == null) {
8199                oldPkg = null;
8200             } else {
8201                oldPkg = oldPkgSetting.pkg;
8202             }
8203
8204             // If we're only installing presumed-existing packages, require that the
8205             // scanned APK is both already known and at the path previously established
8206             // for it.  Previously unknown packages we pick up normally, but if we have an
8207             // a priori expectation about this package's install presence, enforce it.
8208             // With a singular exception for new system packages. When an OTA contains
8209             // a new system package, we allow the codepath to change from a system location
8210             // to the user-installed location. If we don't allow this change, any newer,
8211             // user-installed version of the application will be ignored.
8212             if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
8213                 if (mExpectingBetter.containsKey(pkg.packageName)) {
8214                     logCriticalInfo(Log.WARN,
8215                             "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
8216                 } else {
8217                     PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
8218                     if (known != null) {
8219                         if (DEBUG_PACKAGE_SCANNING) {
8220                             Log.d(TAG, "Examining " + pkg.codePath
8221                                     + " and requiring known paths " + known.codePathString
8222                                     + " & " + known.resourcePathString);
8223                         }
8224                         if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
8225                                 || !pkg.applicationInfo.getResourcePath().equals(
8226                                 known.resourcePathString)) {
8227                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
8228                                     "Application package " + pkg.packageName
8229                                             + " found at " + pkg.applicationInfo.getCodePath()
8230                                             + " but expected at " + known.codePathString
8231                                             + "; ignoring.");
8232                         }
8233                     }
8234                 }
8235             }
8236         }
8237
8238         // Initialize package source and resource directories
8239         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
8240         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
8241
8242         SharedUserSetting suid = null;
8243         PackageSetting pkgSetting = null;
8244
8245         if (!isSystemApp(pkg)) {
8246             // Only system apps can use these features.
8247             pkg.mOriginalPackages = null;
8248             pkg.mRealPackage = null;
8249             pkg.mAdoptPermissions = null;
8250         }
8251
8252         // Getting the package setting may have a side-effect, so if we
8253         // are only checking if scan would succeed, stash a copy of the
8254         // old setting to restore at the end.
8255         PackageSetting nonMutatedPs = null;
8256
8257         // writer
8258         synchronized (mPackages) {
8259             if (pkg.mSharedUserId != null) {
8260                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
8261                 if (suid == null) {
8262                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8263                             "Creating application package " + pkg.packageName
8264                             + " for shared user failed");
8265                 }
8266                 if (DEBUG_PACKAGE_SCANNING) {
8267                     if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8268                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
8269                                 + "): packages=" + suid.packages);
8270                 }
8271             }
8272
8273             // Check if we are renaming from an original package name.
8274             PackageSetting origPackage = null;
8275             String realName = null;
8276             if (pkg.mOriginalPackages != null) {
8277                 // This package may need to be renamed to a previously
8278                 // installed name.  Let's check on that...
8279                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
8280                 if (pkg.mOriginalPackages.contains(renamed)) {
8281                     // This package had originally been installed as the
8282                     // original name, and we have already taken care of
8283                     // transitioning to the new one.  Just update the new
8284                     // one to continue using the old name.
8285                     realName = pkg.mRealPackage;
8286                     if (!pkg.packageName.equals(renamed)) {
8287                         // Callers into this function may have already taken
8288                         // care of renaming the package; only do it here if
8289                         // it is not already done.
8290                         pkg.setPackageName(renamed);
8291                     }
8292
8293                 } else {
8294                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
8295                         if ((origPackage = mSettings.peekPackageLPr(
8296                                 pkg.mOriginalPackages.get(i))) != null) {
8297                             // We do have the package already installed under its
8298                             // original name...  should we use it?
8299                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
8300                                 // New package is not compatible with original.
8301                                 origPackage = null;
8302                                 continue;
8303                             } else if (origPackage.sharedUser != null) {
8304                                 // Make sure uid is compatible between packages.
8305                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
8306                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
8307                                             + " to " + pkg.packageName + ": old uid "
8308                                             + origPackage.sharedUser.name
8309                                             + " differs from " + pkg.mSharedUserId);
8310                                     origPackage = null;
8311                                     continue;
8312                                 }
8313                                 // TODO: Add case when shared user id is added [b/28144775]
8314                             } else {
8315                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
8316                                         + pkg.packageName + " to old name " + origPackage.name);
8317                             }
8318                             break;
8319                         }
8320                     }
8321                 }
8322             }
8323
8324             if (mTransferedPackages.contains(pkg.packageName)) {
8325                 Slog.w(TAG, "Package " + pkg.packageName
8326                         + " was transferred to another, but its .apk remains");
8327             }
8328
8329             // See comments in nonMutatedPs declaration
8330             if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8331                 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName);
8332                 if (foundPs != null) {
8333                     nonMutatedPs = new PackageSetting(foundPs);
8334                 }
8335             }
8336
8337             // Just create the setting, don't add it yet. For already existing packages
8338             // the PkgSetting exists already and doesn't have to be created.
8339             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
8340                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
8341                     pkg.applicationInfo.primaryCpuAbi,
8342                     pkg.applicationInfo.secondaryCpuAbi,
8343                     pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
8344                     user, false);
8345             if (pkgSetting == null) {
8346                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8347                         "Creating application package " + pkg.packageName + " failed");
8348             }
8349
8350             if (pkgSetting.origPackage != null) {
8351                 // If we are first transitioning from an original package,
8352                 // fix up the new package's name now.  We need to do this after
8353                 // looking up the package under its new name, so getPackageLP
8354                 // can take care of fiddling things correctly.
8355                 pkg.setPackageName(origPackage.name);
8356
8357                 // File a report about this.
8358                 String msg = "New package " + pkgSetting.realName
8359                         + " renamed to replace old package " + pkgSetting.name;
8360                 reportSettingsProblem(Log.WARN, msg);
8361
8362                 // Make a note of it.
8363                 if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8364                     mTransferedPackages.add(origPackage.name);
8365                 }
8366
8367                 // No longer need to retain this.
8368                 pkgSetting.origPackage = null;
8369             }
8370
8371             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
8372                 // Make a note of it.
8373                 mTransferedPackages.add(pkg.packageName);
8374             }
8375
8376             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
8377                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
8378             }
8379
8380             if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8381                 // Check all shared libraries and map to their actual file path.
8382                 // We only do this here for apps not on a system dir, because those
8383                 // are the only ones that can fail an install due to this.  We
8384                 // will take care of the system apps by updating all of their
8385                 // library paths after the scan is done.
8386                 updateSharedLibrariesLPw(pkg, null);
8387             }
8388
8389             if (mFoundPolicyFile) {
8390                 SELinuxMMAC.assignSeinfoValue(pkg);
8391             }
8392
8393             pkg.applicationInfo.uid = pkgSetting.appId;
8394             pkg.mExtras = pkgSetting;
8395             if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
8396                 if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
8397                     // We just determined the app is signed correctly, so bring
8398                     // over the latest parsed certs.
8399                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8400                 } else {
8401                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8402                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
8403                                 "Package " + pkg.packageName + " upgrade keys do not match the "
8404                                 + "previously installed version");
8405                     } else {
8406                         pkgSetting.signatures.mSignatures = pkg.mSignatures;
8407                         String msg = "System package " + pkg.packageName
8408                             + " signature changed; retaining data.";
8409                         reportSettingsProblem(Log.WARN, msg);
8410                     }
8411                 }
8412             } else {
8413                 try {
8414                     verifySignaturesLP(pkgSetting, pkg);
8415                     // We just determined the app is signed correctly, so bring
8416                     // over the latest parsed certs.
8417                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8418                 } catch (PackageManagerException e) {
8419                     if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8420                         throw e;
8421                     }
8422                     // The signature has changed, but this package is in the system
8423                     // image...  let's recover!
8424                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
8425                     // However...  if this package is part of a shared user, but it
8426                     // doesn't match the signature of the shared user, let's fail.
8427                     // What this means is that you can't change the signatures
8428                     // associated with an overall shared user, which doesn't seem all
8429                     // that unreasonable.
8430                     if (pkgSetting.sharedUser != null) {
8431                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8432                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
8433                             throw new PackageManagerException(
8434                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
8435                                             "Signature mismatch for shared user: "
8436                                             + pkgSetting.sharedUser);
8437                         }
8438                     }
8439                     // File a report about this.
8440                     String msg = "System package " + pkg.packageName
8441                         + " signature changed; retaining data.";
8442                     reportSettingsProblem(Log.WARN, msg);
8443                 }
8444             }
8445             // Verify that this new package doesn't have any content providers
8446             // that conflict with existing packages.  Only do this if the
8447             // package isn't already installed, since we don't want to break
8448             // things that are installed.
8449             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
8450                 final int N = pkg.providers.size();
8451                 int i;
8452                 for (i=0; i<N; i++) {
8453                     PackageParser.Provider p = pkg.providers.get(i);
8454                     if (p.info.authority != null) {
8455                         String names[] = p.info.authority.split(";");
8456                         for (int j = 0; j < names.length; j++) {
8457                             if (mProvidersByAuthority.containsKey(names[j])) {
8458                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8459                                 final String otherPackageName =
8460                                         ((other != null && other.getComponentName() != null) ?
8461                                                 other.getComponentName().getPackageName() : "?");
8462                                 throw new PackageManagerException(
8463                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
8464                                                 "Can't install because provider name " + names[j]
8465                                                 + " (in package " + pkg.applicationInfo.packageName
8466                                                 + ") is already used by " + otherPackageName);
8467                             }
8468                         }
8469                     }
8470                 }
8471             }
8472
8473             if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
8474                 // This package wants to adopt ownership of permissions from
8475                 // another package.
8476                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
8477                     final String origName = pkg.mAdoptPermissions.get(i);
8478                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
8479                     if (orig != null) {
8480                         if (verifyPackageUpdateLPr(orig, pkg)) {
8481                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
8482                                     + pkg.packageName);
8483                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
8484                         }
8485                     }
8486                 }
8487             }
8488         }
8489
8490         final String pkgName = pkg.packageName;
8491
8492         final long scanFileTime = getLastModifiedTime(pkg, scanFile);
8493         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
8494         pkg.applicationInfo.processName = fixProcessName(
8495                 pkg.applicationInfo.packageName,
8496                 pkg.applicationInfo.processName,
8497                 pkg.applicationInfo.uid);
8498
8499         if (pkg != mPlatformPackage) {
8500             // Get all of our default paths setup
8501             pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
8502         }
8503
8504         final String path = scanFile.getPath();
8505         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
8506
8507         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
8508             derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
8509
8510             // Some system apps still use directory structure for native libraries
8511             // in which case we might end up not detecting abi solely based on apk
8512             // structure. Try to detect abi based on directory structure.
8513             if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
8514                     pkg.applicationInfo.primaryCpuAbi == null) {
8515                 setBundledAppAbisAndRoots(pkg, pkgSetting);
8516                 setNativeLibraryPaths(pkg);
8517             }
8518
8519         } else {
8520             if ((scanFlags & SCAN_MOVE) != 0) {
8521                 // We haven't run dex-opt for this move (since we've moved the compiled output too)
8522                 // but we already have this packages package info in the PackageSetting. We just
8523                 // use that and derive the native library path based on the new codepath.
8524                 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
8525                 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
8526             }
8527
8528             // Set native library paths again. For moves, the path will be updated based on the
8529             // ABIs we've determined above. For non-moves, the path will be updated based on the
8530             // ABIs we determined during compilation, but the path will depend on the final
8531             // package path (after the rename away from the stage path).
8532             setNativeLibraryPaths(pkg);
8533         }
8534
8535         // This is a special case for the "system" package, where the ABI is
8536         // dictated by the zygote configuration (and init.rc). We should keep track
8537         // of this ABI so that we can deal with "normal" applications that run under
8538         // the same UID correctly.
8539         if (mPlatformPackage == pkg) {
8540             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
8541                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
8542         }
8543
8544         // If there's a mismatch between the abi-override in the package setting
8545         // and the abiOverride specified for the install. Warn about this because we
8546         // would've already compiled the app without taking the package setting into
8547         // account.
8548         if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
8549             if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
8550                 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
8551                         " for package " + pkg.packageName);
8552             }
8553         }
8554
8555         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8556         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8557         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
8558
8559         // Copy the derived override back to the parsed package, so that we can
8560         // update the package settings accordingly.
8561         pkg.cpuAbiOverride = cpuAbiOverride;
8562
8563         if (DEBUG_ABI_SELECTION) {
8564             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
8565                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
8566                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
8567         }
8568
8569         // Push the derived path down into PackageSettings so we know what to
8570         // clean up at uninstall time.
8571         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
8572
8573         if (DEBUG_ABI_SELECTION) {
8574             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
8575                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
8576                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
8577         }
8578
8579         if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
8580             // We don't do this here during boot because we can do it all
8581             // at once after scanning all existing packages.
8582             //
8583             // We also do this *before* we perform dexopt on this package, so that
8584             // we can avoid redundant dexopts, and also to make sure we've got the
8585             // code and package path correct.
8586             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
8587                     pkg, true /* boot complete */);
8588         }
8589
8590         if (mFactoryTest && pkg.requestedPermissions.contains(
8591                 android.Manifest.permission.FACTORY_TEST)) {
8592             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
8593         }
8594
8595         if (isSystemApp(pkg)) {
8596             pkgSetting.isOrphaned = true;
8597         }
8598
8599         ArrayList<PackageParser.Package> clientLibPkgs = null;
8600
8601         if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8602             if (nonMutatedPs != null) {
8603                 synchronized (mPackages) {
8604                     mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
8605                 }
8606             }
8607             return pkg;
8608         }
8609
8610         // Only privileged apps and updated privileged apps can add child packages.
8611         if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
8612             if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
8613                 throw new PackageManagerException("Only privileged apps and updated "
8614                         + "privileged apps can add child packages. Ignoring package "
8615                         + pkg.packageName);
8616             }
8617             final int childCount = pkg.childPackages.size();
8618             for (int i = 0; i < childCount; i++) {
8619                 PackageParser.Package childPkg = pkg.childPackages.get(i);
8620                 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
8621                         childPkg.packageName)) {
8622                     throw new PackageManagerException("Cannot override a child package of "
8623                             + "another disabled system app. Ignoring package " + pkg.packageName);
8624                 }
8625             }
8626         }
8627
8628         // writer
8629         synchronized (mPackages) {
8630             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8631                 // Only system apps can add new shared libraries.
8632                 if (pkg.libraryNames != null) {
8633                     for (int i=0; i<pkg.libraryNames.size(); i++) {
8634                         String name = pkg.libraryNames.get(i);
8635                         boolean allowed = false;
8636                         if (pkg.isUpdatedSystemApp()) {
8637                             // New library entries can only be added through the
8638                             // system image.  This is important to get rid of a lot
8639                             // of nasty edge cases: for example if we allowed a non-
8640                             // system update of the app to add a library, then uninstalling
8641                             // the update would make the library go away, and assumptions
8642                             // we made such as through app install filtering would now
8643                             // have allowed apps on the device which aren't compatible
8644                             // with it.  Better to just have the restriction here, be
8645                             // conservative, and create many fewer cases that can negatively
8646                             // impact the user experience.
8647                             final PackageSetting sysPs = mSettings
8648                                     .getDisabledSystemPkgLPr(pkg.packageName);
8649                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
8650                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
8651                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
8652                                         allowed = true;
8653                                         break;
8654                                     }
8655                                 }
8656                             }
8657                         } else {
8658                             allowed = true;
8659                         }
8660                         if (allowed) {
8661                             if (!mSharedLibraries.containsKey(name)) {
8662                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
8663                             } else if (!name.equals(pkg.packageName)) {
8664                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
8665                                         + name + " already exists; skipping");
8666                             }
8667                         } else {
8668                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
8669                                     + name + " that is not declared on system image; skipping");
8670                         }
8671                     }
8672                     if ((scanFlags & SCAN_BOOTING) == 0) {
8673                         // If we are not booting, we need to update any applications
8674                         // that are clients of our shared library.  If we are booting,
8675                         // this will all be done once the scan is complete.
8676                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
8677                     }
8678                 }
8679             }
8680         }
8681
8682         if ((scanFlags & SCAN_BOOTING) != 0) {
8683             // No apps can run during boot scan, so they don't need to be frozen
8684         } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
8685             // Caller asked to not kill app, so it's probably not frozen
8686         } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
8687             // Caller asked us to ignore frozen check for some reason; they
8688             // probably didn't know the package name
8689         } else {
8690             // We're doing major surgery on this package, so it better be frozen
8691             // right now to keep it from launching
8692             checkPackageFrozen(pkgName);
8693         }
8694
8695         // Also need to kill any apps that are dependent on the library.
8696         if (clientLibPkgs != null) {
8697             for (int i=0; i<clientLibPkgs.size(); i++) {
8698                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
8699                 killApplication(clientPkg.applicationInfo.packageName,
8700                         clientPkg.applicationInfo.uid, "update lib");
8701             }
8702         }
8703
8704         // Make sure we're not adding any bogus keyset info
8705         KeySetManagerService ksms = mSettings.mKeySetManagerService;
8706         ksms.assertScannedPackageValid(pkg);
8707
8708         // writer
8709         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
8710
8711         boolean createIdmapFailed = false;
8712         synchronized (mPackages) {
8713             // We don't expect installation to fail beyond this point
8714
8715             if (pkgSetting.pkg != null) {
8716                 // Note that |user| might be null during the initial boot scan. If a codePath
8717                 // for an app has changed during a boot scan, it's due to an app update that's
8718                 // part of the system partition and marker changes must be applied to all users.
8719                 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg,
8720                     (user != null) ? user : UserHandle.ALL);
8721             }
8722
8723             // Add the new setting to mSettings
8724             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
8725             // Add the new setting to mPackages
8726             mPackages.put(pkg.applicationInfo.packageName, pkg);
8727             // Make sure we don't accidentally delete its data.
8728             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
8729             while (iter.hasNext()) {
8730                 PackageCleanItem item = iter.next();
8731                 if (pkgName.equals(item.packageName)) {
8732                     iter.remove();
8733                 }
8734             }
8735
8736             // Take care of first install / last update times.
8737             if (currentTime != 0) {
8738                 if (pkgSetting.firstInstallTime == 0) {
8739                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
8740                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
8741                     pkgSetting.lastUpdateTime = currentTime;
8742                 }
8743             } else if (pkgSetting.firstInstallTime == 0) {
8744                 // We need *something*.  Take time time stamp of the file.
8745                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
8746             } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
8747                 if (scanFileTime != pkgSetting.timeStamp) {
8748                     // A package on the system image has changed; consider this
8749                     // to be an update.
8750                     pkgSetting.lastUpdateTime = scanFileTime;
8751                 }
8752             }
8753
8754             // Add the package's KeySets to the global KeySetManagerService
8755             ksms.addScannedPackageLPw(pkg);
8756
8757             int N = pkg.providers.size();
8758             StringBuilder r = null;
8759             int i;
8760             for (i=0; i<N; i++) {
8761                 PackageParser.Provider p = pkg.providers.get(i);
8762                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
8763                         p.info.processName, pkg.applicationInfo.uid);
8764                 mProviders.addProvider(p);
8765                 p.syncable = p.info.isSyncable;
8766                 if (p.info.authority != null) {
8767                     String names[] = p.info.authority.split(";");
8768                     p.info.authority = null;
8769                     for (int j = 0; j < names.length; j++) {
8770                         if (j == 1 && p.syncable) {
8771                             // We only want the first authority for a provider to possibly be
8772                             // syncable, so if we already added this provider using a different
8773                             // authority clear the syncable flag. We copy the provider before
8774                             // changing it because the mProviders object contains a reference
8775                             // to a provider that we don't want to change.
8776                             // Only do this for the second authority since the resulting provider
8777                             // object can be the same for all future authorities for this provider.
8778                             p = new PackageParser.Provider(p);
8779                             p.syncable = false;
8780                         }
8781                         if (!mProvidersByAuthority.containsKey(names[j])) {
8782                             mProvidersByAuthority.put(names[j], p);
8783                             if (p.info.authority == null) {
8784                                 p.info.authority = names[j];
8785                             } else {
8786                                 p.info.authority = p.info.authority + ";" + names[j];
8787                             }
8788                             if (DEBUG_PACKAGE_SCANNING) {
8789                                 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8790                                     Log.d(TAG, "Registered content provider: " + names[j]
8791                                             + ", className = " + p.info.name + ", isSyncable = "
8792                                             + p.info.isSyncable);
8793                             }
8794                         } else {
8795                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8796                             Slog.w(TAG, "Skipping provider name " + names[j] +
8797                                     " (in package " + pkg.applicationInfo.packageName +
8798                                     "): name already used by "
8799                                     + ((other != null && other.getComponentName() != null)
8800                                             ? other.getComponentName().getPackageName() : "?"));
8801                         }
8802                     }
8803                 }
8804                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8805                     if (r == null) {
8806                         r = new StringBuilder(256);
8807                     } else {
8808                         r.append(' ');
8809                     }
8810                     r.append(p.info.name);
8811                 }
8812             }
8813             if (r != null) {
8814                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
8815             }
8816
8817             N = pkg.services.size();
8818             r = null;
8819             for (i=0; i<N; i++) {
8820                 PackageParser.Service s = pkg.services.get(i);
8821                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
8822                         s.info.processName, pkg.applicationInfo.uid);
8823                 mServices.addService(s);
8824                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8825                     if (r == null) {
8826                         r = new StringBuilder(256);
8827                     } else {
8828                         r.append(' ');
8829                     }
8830                     r.append(s.info.name);
8831                 }
8832             }
8833             if (r != null) {
8834                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
8835             }
8836
8837             N = pkg.receivers.size();
8838             r = null;
8839             for (i=0; i<N; i++) {
8840                 PackageParser.Activity a = pkg.receivers.get(i);
8841                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8842                         a.info.processName, pkg.applicationInfo.uid);
8843                 mReceivers.addActivity(a, "receiver");
8844                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8845                     if (r == null) {
8846                         r = new StringBuilder(256);
8847                     } else {
8848                         r.append(' ');
8849                     }
8850                     r.append(a.info.name);
8851                 }
8852             }
8853             if (r != null) {
8854                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
8855             }
8856
8857             N = pkg.activities.size();
8858             r = null;
8859             for (i=0; i<N; i++) {
8860                 PackageParser.Activity a = pkg.activities.get(i);
8861                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8862                         a.info.processName, pkg.applicationInfo.uid);
8863                 mActivities.addActivity(a, "activity");
8864                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8865                     if (r == null) {
8866                         r = new StringBuilder(256);
8867                     } else {
8868                         r.append(' ');
8869                     }
8870                     r.append(a.info.name);
8871                 }
8872             }
8873             if (r != null) {
8874                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
8875             }
8876
8877             N = pkg.permissionGroups.size();
8878             r = null;
8879             for (i=0; i<N; i++) {
8880                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
8881                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
8882                 final String curPackageName = cur == null ? null : cur.info.packageName;
8883                 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
8884                 if (cur == null || isPackageUpdate) {
8885                     mPermissionGroups.put(pg.info.name, pg);
8886                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8887                         if (r == null) {
8888                             r = new StringBuilder(256);
8889                         } else {
8890                             r.append(' ');
8891                         }
8892                         if (isPackageUpdate) {
8893                             r.append("UPD:");
8894                         }
8895                         r.append(pg.info.name);
8896                     }
8897                 } else {
8898                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
8899                             + pg.info.packageName + " ignored: original from "
8900                             + cur.info.packageName);
8901                     if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8902                         if (r == null) {
8903                             r = new StringBuilder(256);
8904                         } else {
8905                             r.append(' ');
8906                         }
8907                         r.append("DUP:");
8908                         r.append(pg.info.name);
8909                     }
8910                 }
8911             }
8912             if (r != null) {
8913                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
8914             }
8915
8916             N = pkg.permissions.size();
8917             r = null;
8918             for (i=0; i<N; i++) {
8919                 PackageParser.Permission p = pkg.permissions.get(i);
8920
8921                 // Assume by default that we did not install this permission into the system.
8922                 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
8923
8924                 // Now that permission groups have a special meaning, we ignore permission
8925                 // groups for legacy apps to prevent unexpected behavior. In particular,
8926                 // permissions for one app being granted to someone just becase they happen
8927                 // to be in a group defined by another app (before this had no implications).
8928                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
8929                     p.group = mPermissionGroups.get(p.info.group);
8930                     // Warn for a permission in an unknown group.
8931                     if (p.info.group != null && p.group == null) {
8932                         Slog.w(TAG, "Permission " + p.info.name + " from package "
8933                                 + p.info.packageName + " in an unknown group " + p.info.group);
8934                     }
8935                 }
8936
8937                 ArrayMap<String, BasePermission> permissionMap =
8938                         p.tree ? mSettings.mPermissionTrees
8939                                 : mSettings.mPermissions;
8940                 BasePermission bp = permissionMap.get(p.info.name);
8941
8942                 // Allow system apps to redefine non-system permissions
8943                 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
8944                     final boolean currentOwnerIsSystem = (bp.perm != null
8945                             && isSystemApp(bp.perm.owner));
8946                     if (isSystemApp(p.owner)) {
8947                         if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
8948                             // It's a built-in permission and no owner, take ownership now
8949                             bp.packageSetting = pkgSetting;
8950                             bp.perm = p;
8951                             bp.uid = pkg.applicationInfo.uid;
8952                             bp.sourcePackage = p.info.packageName;
8953                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8954                         } else if (!currentOwnerIsSystem) {
8955                             String msg = "New decl " + p.owner + " of permission  "
8956                                     + p.info.name + " is system; overriding " + bp.sourcePackage;
8957                             reportSettingsProblem(Log.WARN, msg);
8958                             bp = null;
8959                         }
8960                     }
8961                 }
8962
8963                 if (bp == null) {
8964                     bp = new BasePermission(p.info.name, p.info.packageName,
8965                             BasePermission.TYPE_NORMAL);
8966                     permissionMap.put(p.info.name, bp);
8967                 }
8968
8969                 if (bp.perm == null) {
8970                     if (bp.sourcePackage == null
8971                             || bp.sourcePackage.equals(p.info.packageName)) {
8972                         BasePermission tree = findPermissionTreeLP(p.info.name);
8973                         if (tree == null
8974                                 || tree.sourcePackage.equals(p.info.packageName)) {
8975                             bp.packageSetting = pkgSetting;
8976                             bp.perm = p;
8977                             bp.uid = pkg.applicationInfo.uid;
8978                             bp.sourcePackage = p.info.packageName;
8979                             p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8980                             if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8981                                 if (r == null) {
8982                                     r = new StringBuilder(256);
8983                                 } else {
8984                                     r.append(' ');
8985                                 }
8986                                 r.append(p.info.name);
8987                             }
8988                         } else {
8989                             Slog.w(TAG, "Permission " + p.info.name + " from package "
8990                                     + p.info.packageName + " ignored: base tree "
8991                                     + tree.name + " is from package "
8992                                     + tree.sourcePackage);
8993                         }
8994                     } else {
8995                         Slog.w(TAG, "Permission " + p.info.name + " from package "
8996                                 + p.info.packageName + " ignored: original from "
8997                                 + bp.sourcePackage);
8998                     }
8999                 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
9000                     if (r == null) {
9001                         r = new StringBuilder(256);
9002                     } else {
9003                         r.append(' ');
9004                     }
9005                     r.append("DUP:");
9006                     r.append(p.info.name);
9007                 }
9008                 if (bp.perm == p) {
9009                     bp.protectionLevel = p.info.protectionLevel;
9010                 }
9011             }
9012
9013             if (r != null) {
9014                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
9015             }
9016
9017             N = pkg.instrumentation.size();
9018             r = null;
9019             for (i=0; i<N; i++) {
9020                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
9021                 a.info.packageName = pkg.applicationInfo.packageName;
9022                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
9023                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
9024                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
9025                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
9026                 a.info.dataDir = pkg.applicationInfo.dataDir;
9027                 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
9028                 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
9029
9030                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
9031                 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
9032                 mInstrumentation.put(a.getComponentName(), a);
9033                 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
9034                     if (r == null) {
9035                         r = new StringBuilder(256);
9036                     } else {
9037                         r.append(' ');
9038                     }
9039                     r.append(a.info.name);
9040                 }
9041             }
9042             if (r != null) {
9043                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
9044             }
9045
9046             if (pkg.protectedBroadcasts != null) {
9047                 N = pkg.protectedBroadcasts.size();
9048                 for (i=0; i<N; i++) {
9049                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
9050                 }
9051             }
9052
9053             pkgSetting.setTimeStamp(scanFileTime);
9054
9055             // Create idmap files for pairs of (packages, overlay packages).
9056             // Note: "android", ie framework-res.apk, is handled by native layers.
9057             if (pkg.mOverlayTarget != null) {
9058                 // This is an overlay package.
9059                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
9060                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
9061                         mOverlays.put(pkg.mOverlayTarget,
9062                                 new ArrayMap<String, PackageParser.Package>());
9063                     }
9064                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
9065                     map.put(pkg.packageName, pkg);
9066                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
9067                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
9068                         createIdmapFailed = true;
9069                     }
9070                 }
9071             } else if (mOverlays.containsKey(pkg.packageName) &&
9072                     !pkg.packageName.equals("android")) {
9073                 // This is a regular package, with one or more known overlay packages.
9074                 createIdmapsForPackageLI(pkg);
9075             }
9076
9077             if (oldPkg != null) {
9078                 // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
9079                 // revokation from this method might need to kill apps which need the
9080                 // mPackages lock on a different thread. This would dead lock.
9081                 //
9082                 // Hence create a copy of all package names and pass it into
9083                 // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
9084                 // revoked. If a new package is added before the async code runs the permission
9085                 // won't be granted yet, hence new packages are no problem.
9086                 final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
9087
9088                 AsyncTask.execute(new Runnable() {
9089                     public void run() {
9090                         revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames);
9091                     }
9092                 });
9093             }
9094         }
9095
9096         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9097
9098         if (createIdmapFailed) {
9099             throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9100                     "scanPackageLI failed to createIdmap");
9101         }
9102         return pkg;
9103     }
9104
9105     private void maybeRenameForeignDexMarkers(PackageParser.Package existing,
9106             PackageParser.Package update, UserHandle user) {
9107         if (existing.applicationInfo == null || update.applicationInfo == null) {
9108             // This isn't due to an app installation.
9109             return;
9110         }
9111
9112         final File oldCodePath = new File(existing.applicationInfo.getCodePath());
9113         final File newCodePath = new File(update.applicationInfo.getCodePath());
9114
9115         // The codePath hasn't changed, so there's nothing for us to do.
9116         if (Objects.equals(oldCodePath, newCodePath)) {
9117             return;
9118         }
9119
9120         File canonicalNewCodePath;
9121         try {
9122             canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath));
9123         } catch (IOException e) {
9124             Slog.w(TAG, "Failed to get canonical path.", e);
9125             return;
9126         }
9127
9128         // This is a bit of a hack. The oldCodePath doesn't exist at this point (because
9129         // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume
9130         // that the last component of the path (i.e, the name) doesn't need canonicalization
9131         // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now
9132         // but may change in the future. Hopefully this function won't exist at that point.
9133         final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(),
9134                 oldCodePath.getName());
9135
9136         // Calculate the prefixes of the markers. These are just the paths with "/" replaced
9137         // with "@".
9138         String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@');
9139         if (!oldMarkerPrefix.endsWith("@")) {
9140             oldMarkerPrefix += "@";
9141         }
9142         String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@');
9143         if (!newMarkerPrefix.endsWith("@")) {
9144             newMarkerPrefix += "@";
9145         }
9146
9147         List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly();
9148         List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size());
9149         for (String updatedPath : updatedPaths) {
9150             String updatedPathName = new File(updatedPath).getName();
9151             markerSuffixes.add(updatedPathName.replace('/', '@'));
9152         }
9153
9154         for (int userId : resolveUserIds(user.getIdentifier())) {
9155             File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId);
9156
9157             for (String markerSuffix : markerSuffixes) {
9158                 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix);
9159                 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix);
9160                 if (oldForeignUseMark.exists()) {
9161                     try {
9162                         Os.rename(oldForeignUseMark.getAbsolutePath(),
9163                                 newForeignUseMark.getAbsolutePath());
9164                     } catch (ErrnoException e) {
9165                         Slog.w(TAG, "Failed to rename foreign use marker", e);
9166                         oldForeignUseMark.delete();
9167                     }
9168                 }
9169             }
9170         }
9171     }
9172
9173     /**
9174      * Derive the ABI of a non-system package located at {@code scanFile}. This information
9175      * is derived purely on the basis of the contents of {@code scanFile} and
9176      * {@code cpuAbiOverride}.
9177      *
9178      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
9179      */
9180     private void derivePackageAbi(PackageParser.Package pkg, File scanFile,
9181                                  String cpuAbiOverride, boolean extractLibs)
9182             throws PackageManagerException {
9183         // TODO: We can probably be smarter about this stuff. For installed apps,
9184         // we can calculate this information at install time once and for all. For
9185         // system apps, we can probably assume that this information doesn't change
9186         // after the first boot scan. As things stand, we do lots of unnecessary work.
9187
9188         // Give ourselves some initial paths; we'll come back for another
9189         // pass once we've determined ABI below.
9190         setNativeLibraryPaths(pkg);
9191
9192         // We would never need to extract libs for forward-locked and external packages,
9193         // since the container service will do it for us. We shouldn't attempt to
9194         // extract libs from system app when it was not updated.
9195         if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
9196                 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
9197             extractLibs = false;
9198         }
9199
9200         final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
9201         final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
9202
9203         NativeLibraryHelper.Handle handle = null;
9204         try {
9205             handle = NativeLibraryHelper.Handle.create(pkg);
9206             // TODO(multiArch): This can be null for apps that didn't go through the
9207             // usual installation process. We can calculate it again, like we
9208             // do during install time.
9209             //
9210             // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
9211             // unnecessary.
9212             final File nativeLibraryRoot = new File(nativeLibraryRootStr);
9213
9214             // Null out the abis so that they can be recalculated.
9215             pkg.applicationInfo.primaryCpuAbi = null;
9216             pkg.applicationInfo.secondaryCpuAbi = null;
9217             if (isMultiArch(pkg.applicationInfo)) {
9218                 // Warn if we've set an abiOverride for multi-lib packages..
9219                 // By definition, we need to copy both 32 and 64 bit libraries for
9220                 // such packages.
9221                 if (pkg.cpuAbiOverride != null
9222                         && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
9223                     Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
9224                 }
9225
9226                 int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
9227                 int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
9228                 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
9229                     if (extractLibs) {
9230                         abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9231                                 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
9232                                 useIsaSpecificSubdirs);
9233                     } else {
9234                         abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
9235                     }
9236                 }
9237
9238                 maybeThrowExceptionForMultiArchCopy(
9239                         "Error unpackaging 32 bit native libs for multiarch app.", abi32);
9240
9241                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
9242                     if (extractLibs) {
9243                         abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9244                                 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
9245                                 useIsaSpecificSubdirs);
9246                     } else {
9247                         abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
9248                     }
9249                 }
9250
9251                 maybeThrowExceptionForMultiArchCopy(
9252                         "Error unpackaging 64 bit native libs for multiarch app.", abi64);
9253
9254                 if (abi64 >= 0) {
9255                     pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
9256                 }
9257
9258                 if (abi32 >= 0) {
9259                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
9260                     if (abi64 >= 0) {
9261                         if (pkg.use32bitAbi) {
9262                             pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
9263                             pkg.applicationInfo.primaryCpuAbi = abi;
9264                         } else {
9265                             pkg.applicationInfo.secondaryCpuAbi = abi;
9266                         }
9267                     } else {
9268                         pkg.applicationInfo.primaryCpuAbi = abi;
9269                     }
9270                 }
9271
9272             } else {
9273                 String[] abiList = (cpuAbiOverride != null) ?
9274                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
9275
9276                 // Enable gross and lame hacks for apps that are built with old
9277                 // SDK tools. We must scan their APKs for renderscript bitcode and
9278                 // not launch them if it's present. Don't bother checking on devices
9279                 // that don't have 64 bit support.
9280                 boolean needsRenderScriptOverride = false;
9281                 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
9282                         NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
9283                     abiList = Build.SUPPORTED_32_BIT_ABIS;
9284                     needsRenderScriptOverride = true;
9285                 }
9286
9287                 final int copyRet;
9288                 if (extractLibs) {
9289                     copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9290                             nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
9291                 } else {
9292                     copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
9293                 }
9294
9295                 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
9296                     throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
9297                             "Error unpackaging native libs for app, errorCode=" + copyRet);
9298                 }
9299
9300                 if (copyRet >= 0) {
9301                     pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
9302                 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
9303                     pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
9304                 } else if (needsRenderScriptOverride) {
9305                     pkg.applicationInfo.primaryCpuAbi = abiList[0];
9306                 }
9307             }
9308         } catch (IOException ioe) {
9309             Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
9310         } finally {
9311             IoUtils.closeQuietly(handle);
9312         }
9313
9314         // Now that we've calculated the ABIs and determined if it's an internal app,
9315         // we will go ahead and populate the nativeLibraryPath.
9316         setNativeLibraryPaths(pkg);
9317     }
9318
9319     /**
9320      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
9321      * i.e, so that all packages can be run inside a single process if required.
9322      *
9323      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
9324      * this function will either try and make the ABI for all packages in {@code packagesForUser}
9325      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
9326      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
9327      * updating a package that belongs to a shared user.
9328      *
9329      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
9330      * adds unnecessary complexity.
9331      */
9332     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
9333             PackageParser.Package scannedPackage, boolean bootComplete) {
9334         String requiredInstructionSet = null;
9335         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
9336             requiredInstructionSet = VMRuntime.getInstructionSet(
9337                      scannedPackage.applicationInfo.primaryCpuAbi);
9338         }
9339
9340         PackageSetting requirer = null;
9341         for (PackageSetting ps : packagesForUser) {
9342             // If packagesForUser contains scannedPackage, we skip it. This will happen
9343             // when scannedPackage is an update of an existing package. Without this check,
9344             // we will never be able to change the ABI of any package belonging to a shared
9345             // user, even if it's compatible with other packages.
9346             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9347                 if (ps.primaryCpuAbiString == null) {
9348                     continue;
9349                 }
9350
9351                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
9352                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
9353                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
9354                     // this but there's not much we can do.
9355                     String errorMessage = "Instruction set mismatch, "
9356                             + ((requirer == null) ? "[caller]" : requirer)
9357                             + " requires " + requiredInstructionSet + " whereas " + ps
9358                             + " requires " + instructionSet;
9359                     Slog.w(TAG, errorMessage);
9360                 }
9361
9362                 if (requiredInstructionSet == null) {
9363                     requiredInstructionSet = instructionSet;
9364                     requirer = ps;
9365                 }
9366             }
9367         }
9368
9369         if (requiredInstructionSet != null) {
9370             String adjustedAbi;
9371             if (requirer != null) {
9372                 // requirer != null implies that either scannedPackage was null or that scannedPackage
9373                 // did not require an ABI, in which case we have to adjust scannedPackage to match
9374                 // the ABI of the set (which is the same as requirer's ABI)
9375                 adjustedAbi = requirer.primaryCpuAbiString;
9376                 if (scannedPackage != null) {
9377                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
9378                 }
9379             } else {
9380                 // requirer == null implies that we're updating all ABIs in the set to
9381                 // match scannedPackage.
9382                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
9383             }
9384
9385             for (PackageSetting ps : packagesForUser) {
9386                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9387                     if (ps.primaryCpuAbiString != null) {
9388                         continue;
9389                     }
9390
9391                     ps.primaryCpuAbiString = adjustedAbi;
9392                     if (ps.pkg != null && ps.pkg.applicationInfo != null &&
9393                             !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
9394                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
9395                         Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
9396                                 + " (requirer="
9397                                 + (requirer == null ? "null" : requirer.pkg.packageName)
9398                                 + ", scannedPackage="
9399                                 + (scannedPackage != null ? scannedPackage.packageName : "null")
9400                                 + ")");
9401                         try {
9402                             mInstaller.rmdex(ps.codePathString,
9403                                     getDexCodeInstructionSet(getPreferredInstructionSet()));
9404                         } catch (InstallerException ignored) {
9405                         }
9406                     }
9407                 }
9408             }
9409         }
9410     }
9411
9412     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
9413         synchronized (mPackages) {
9414             mResolverReplaced = true;
9415             // Set up information for custom user intent resolution activity.
9416             mResolveActivity.applicationInfo = pkg.applicationInfo;
9417             mResolveActivity.name = mCustomResolverComponentName.getClassName();
9418             mResolveActivity.packageName = pkg.applicationInfo.packageName;
9419             mResolveActivity.processName = pkg.applicationInfo.packageName;
9420             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9421             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
9422                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9423             mResolveActivity.theme = 0;
9424             mResolveActivity.exported = true;
9425             mResolveActivity.enabled = true;
9426             mResolveInfo.activityInfo = mResolveActivity;
9427             mResolveInfo.priority = 0;
9428             mResolveInfo.preferredOrder = 0;
9429             mResolveInfo.match = 0;
9430             mResolveComponentName = mCustomResolverComponentName;
9431             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
9432                     mResolveComponentName);
9433         }
9434     }
9435
9436     private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
9437         final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
9438
9439         // Set up information for ephemeral installer activity
9440         mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
9441         mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
9442         mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
9443         mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
9444         mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9445         mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
9446                 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9447         mEphemeralInstallerActivity.theme = 0;
9448         mEphemeralInstallerActivity.exported = true;
9449         mEphemeralInstallerActivity.enabled = true;
9450         mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
9451         mEphemeralInstallerInfo.priority = 0;
9452         mEphemeralInstallerInfo.preferredOrder = 1;
9453         mEphemeralInstallerInfo.isDefault = true;
9454         mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
9455                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
9456
9457         if (DEBUG_EPHEMERAL) {
9458             Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
9459         }
9460     }
9461
9462     private static String calculateBundledApkRoot(final String codePathString) {
9463         final File codePath = new File(codePathString);
9464         final File codeRoot;
9465         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
9466             codeRoot = Environment.getRootDirectory();
9467         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
9468             codeRoot = Environment.getOemDirectory();
9469         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
9470             codeRoot = Environment.getVendorDirectory();
9471         } else {
9472             // Unrecognized code path; take its top real segment as the apk root:
9473             // e.g. /something/app/blah.apk => /something
9474             try {
9475                 File f = codePath.getCanonicalFile();
9476                 File parent = f.getParentFile();    // non-null because codePath is a file
9477                 File tmp;
9478                 while ((tmp = parent.getParentFile()) != null) {
9479                     f = parent;
9480                     parent = tmp;
9481                 }
9482                 codeRoot = f;
9483                 Slog.w(TAG, "Unrecognized code path "
9484                         + codePath + " - using " + codeRoot);
9485             } catch (IOException e) {
9486                 // Can't canonicalize the code path -- shenanigans?
9487                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
9488                 return Environment.getRootDirectory().getPath();
9489             }
9490         }
9491         return codeRoot.getPath();
9492     }
9493
9494     /**
9495      * Derive and set the location of native libraries for the given package,
9496      * which varies depending on where and how the package was installed.
9497      */
9498     private void setNativeLibraryPaths(PackageParser.Package pkg) {
9499         final ApplicationInfo info = pkg.applicationInfo;
9500         final String codePath = pkg.codePath;
9501         final File codeFile = new File(codePath);
9502         final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
9503         final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
9504
9505         info.nativeLibraryRootDir = null;
9506         info.nativeLibraryRootRequiresIsa = false;
9507         info.nativeLibraryDir = null;
9508         info.secondaryNativeLibraryDir = null;
9509
9510         if (isApkFile(codeFile)) {
9511             // Monolithic install
9512             if (bundledApp) {
9513                 // If "/system/lib64/apkname" exists, assume that is the per-package
9514                 // native library directory to use; otherwise use "/system/lib/apkname".
9515                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
9516                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
9517                         getPrimaryInstructionSet(info));
9518
9519                 // This is a bundled system app so choose the path based on the ABI.
9520                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
9521                 // is just the default path.
9522                 final String apkName = deriveCodePathName(codePath);
9523                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
9524                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
9525                         apkName).getAbsolutePath();
9526
9527                 if (info.secondaryCpuAbi != null) {
9528                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
9529                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
9530                             secondaryLibDir, apkName).getAbsolutePath();
9531                 }
9532             } else if (asecApp) {
9533                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
9534                         .getAbsolutePath();
9535             } else {
9536                 final String apkName = deriveCodePathName(codePath);
9537                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
9538                         .getAbsolutePath();
9539             }
9540
9541             info.nativeLibraryRootRequiresIsa = false;
9542             info.nativeLibraryDir = info.nativeLibraryRootDir;
9543         } else {
9544             // Cluster install
9545             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
9546             info.nativeLibraryRootRequiresIsa = true;
9547
9548             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
9549                     getPrimaryInstructionSet(info)).getAbsolutePath();
9550
9551             if (info.secondaryCpuAbi != null) {
9552                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
9553                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
9554             }
9555         }
9556     }
9557
9558     /**
9559      * Calculate the abis and roots for a bundled app. These can uniquely
9560      * be determined from the contents of the system partition, i.e whether
9561      * it contains 64 or 32 bit shared libraries etc. We do not validate any
9562      * of this information, and instead assume that the system was built
9563      * sensibly.
9564      */
9565     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
9566                                            PackageSetting pkgSetting) {
9567         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
9568
9569         // If "/system/lib64/apkname" exists, assume that is the per-package
9570         // native library directory to use; otherwise use "/system/lib/apkname".
9571         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
9572         setBundledAppAbi(pkg, apkRoot, apkName);
9573         // pkgSetting might be null during rescan following uninstall of updates
9574         // to a bundled app, so accommodate that possibility.  The settings in
9575         // that case will be established later from the parsed package.
9576         //
9577         // If the settings aren't null, sync them up with what we've just derived.
9578         // note that apkRoot isn't stored in the package settings.
9579         if (pkgSetting != null) {
9580             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9581             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9582         }
9583     }
9584
9585     /**
9586      * Deduces the ABI of a bundled app and sets the relevant fields on the
9587      * parsed pkg object.
9588      *
9589      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
9590      *        under which system libraries are installed.
9591      * @param apkName the name of the installed package.
9592      */
9593     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
9594         final File codeFile = new File(pkg.codePath);
9595
9596         final boolean has64BitLibs;
9597         final boolean has32BitLibs;
9598         if (isApkFile(codeFile)) {
9599             // Monolithic install
9600             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
9601             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
9602         } else {
9603             // Cluster install
9604             final File rootDir = new File(codeFile, LIB_DIR_NAME);
9605             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
9606                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
9607                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
9608                 has64BitLibs = (new File(rootDir, isa)).exists();
9609             } else {
9610                 has64BitLibs = false;
9611             }
9612             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
9613                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
9614                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
9615                 has32BitLibs = (new File(rootDir, isa)).exists();
9616             } else {
9617                 has32BitLibs = false;
9618             }
9619         }
9620
9621         if (has64BitLibs && !has32BitLibs) {
9622             // The package has 64 bit libs, but not 32 bit libs. Its primary
9623             // ABI should be 64 bit. We can safely assume here that the bundled
9624             // native libraries correspond to the most preferred ABI in the list.
9625
9626             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9627             pkg.applicationInfo.secondaryCpuAbi = null;
9628         } else if (has32BitLibs && !has64BitLibs) {
9629             // The package has 32 bit libs but not 64 bit libs. Its primary
9630             // ABI should be 32 bit.
9631
9632             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9633             pkg.applicationInfo.secondaryCpuAbi = null;
9634         } else if (has32BitLibs && has64BitLibs) {
9635             // The application has both 64 and 32 bit bundled libraries. We check
9636             // here that the app declares multiArch support, and warn if it doesn't.
9637             //
9638             // We will be lenient here and record both ABIs. The primary will be the
9639             // ABI that's higher on the list, i.e, a device that's configured to prefer
9640             // 64 bit apps will see a 64 bit primary ABI,
9641
9642             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
9643                 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
9644             }
9645
9646             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
9647                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9648                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9649             } else {
9650                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9651                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9652             }
9653         } else {
9654             pkg.applicationInfo.primaryCpuAbi = null;
9655             pkg.applicationInfo.secondaryCpuAbi = null;
9656         }
9657     }
9658
9659     private void killApplication(String pkgName, int appId, String reason) {
9660         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
9661     }
9662
9663     private void killApplication(String pkgName, int appId, int userId, String reason) {
9664         // Request the ActivityManager to kill the process(only for existing packages)
9665         // so that we do not end up in a confused state while the user is still using the older
9666         // version of the application while the new one gets installed.
9667         final long token = Binder.clearCallingIdentity();
9668         try {
9669             IActivityManager am = ActivityManagerNative.getDefault();
9670             if (am != null) {
9671                 try {
9672                     am.killApplication(pkgName, appId, userId, reason);
9673                 } catch (RemoteException e) {
9674                 }
9675             }
9676         } finally {
9677             Binder.restoreCallingIdentity(token);
9678         }
9679     }
9680
9681     private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
9682         // Remove the parent package setting
9683         PackageSetting ps = (PackageSetting) pkg.mExtras;
9684         if (ps != null) {
9685             removePackageLI(ps, chatty);
9686         }
9687         // Remove the child package setting
9688         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9689         for (int i = 0; i < childCount; i++) {
9690             PackageParser.Package childPkg = pkg.childPackages.get(i);
9691             ps = (PackageSetting) childPkg.mExtras;
9692             if (ps != null) {
9693                 removePackageLI(ps, chatty);
9694             }
9695         }
9696     }
9697
9698     void removePackageLI(PackageSetting ps, boolean chatty) {
9699         if (DEBUG_INSTALL) {
9700             if (chatty)
9701                 Log.d(TAG, "Removing package " + ps.name);
9702         }
9703
9704         // writer
9705         synchronized (mPackages) {
9706             mPackages.remove(ps.name);
9707             final PackageParser.Package pkg = ps.pkg;
9708             if (pkg != null) {
9709                 cleanPackageDataStructuresLILPw(pkg, chatty);
9710             }
9711         }
9712     }
9713
9714     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
9715         if (DEBUG_INSTALL) {
9716             if (chatty)
9717                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
9718         }
9719
9720         // writer
9721         synchronized (mPackages) {
9722             // Remove the parent package
9723             mPackages.remove(pkg.applicationInfo.packageName);
9724             cleanPackageDataStructuresLILPw(pkg, chatty);
9725
9726             // Remove the child packages
9727             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9728             for (int i = 0; i < childCount; i++) {
9729                 PackageParser.Package childPkg = pkg.childPackages.get(i);
9730                 mPackages.remove(childPkg.applicationInfo.packageName);
9731                 cleanPackageDataStructuresLILPw(childPkg, chatty);
9732             }
9733         }
9734     }
9735
9736     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
9737         int N = pkg.providers.size();
9738         StringBuilder r = null;
9739         int i;
9740         for (i=0; i<N; i++) {
9741             PackageParser.Provider p = pkg.providers.get(i);
9742             mProviders.removeProvider(p);
9743             if (p.info.authority == null) {
9744
9745                 /* There was another ContentProvider with this authority when
9746                  * this app was installed so this authority is null,
9747                  * Ignore it as we don't have to unregister the provider.
9748                  */
9749                 continue;
9750             }
9751             String names[] = p.info.authority.split(";");
9752             for (int j = 0; j < names.length; j++) {
9753                 if (mProvidersByAuthority.get(names[j]) == p) {
9754                     mProvidersByAuthority.remove(names[j]);
9755                     if (DEBUG_REMOVE) {
9756                         if (chatty)
9757                             Log.d(TAG, "Unregistered content provider: " + names[j]
9758                                     + ", className = " + p.info.name + ", isSyncable = "
9759                                     + p.info.isSyncable);
9760                     }
9761                 }
9762             }
9763             if (DEBUG_REMOVE && chatty) {
9764                 if (r == null) {
9765                     r = new StringBuilder(256);
9766                 } else {
9767                     r.append(' ');
9768                 }
9769                 r.append(p.info.name);
9770             }
9771         }
9772         if (r != null) {
9773             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
9774         }
9775
9776         N = pkg.services.size();
9777         r = null;
9778         for (i=0; i<N; i++) {
9779             PackageParser.Service s = pkg.services.get(i);
9780             mServices.removeService(s);
9781             if (chatty) {
9782                 if (r == null) {
9783                     r = new StringBuilder(256);
9784                 } else {
9785                     r.append(' ');
9786                 }
9787                 r.append(s.info.name);
9788             }
9789         }
9790         if (r != null) {
9791             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
9792         }
9793
9794         N = pkg.receivers.size();
9795         r = null;
9796         for (i=0; i<N; i++) {
9797             PackageParser.Activity a = pkg.receivers.get(i);
9798             mReceivers.removeActivity(a, "receiver");
9799             if (DEBUG_REMOVE && chatty) {
9800                 if (r == null) {
9801                     r = new StringBuilder(256);
9802                 } else {
9803                     r.append(' ');
9804                 }
9805                 r.append(a.info.name);
9806             }
9807         }
9808         if (r != null) {
9809             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
9810         }
9811
9812         N = pkg.activities.size();
9813         r = null;
9814         for (i=0; i<N; i++) {
9815             PackageParser.Activity a = pkg.activities.get(i);
9816             mActivities.removeActivity(a, "activity");
9817             if (DEBUG_REMOVE && chatty) {
9818                 if (r == null) {
9819                     r = new StringBuilder(256);
9820                 } else {
9821                     r.append(' ');
9822                 }
9823                 r.append(a.info.name);
9824             }
9825         }
9826         if (r != null) {
9827             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
9828         }
9829
9830         N = pkg.permissions.size();
9831         r = null;
9832         for (i=0; i<N; i++) {
9833             PackageParser.Permission p = pkg.permissions.get(i);
9834             BasePermission bp = mSettings.mPermissions.get(p.info.name);
9835             if (bp == null) {
9836                 bp = mSettings.mPermissionTrees.get(p.info.name);
9837             }
9838             if (bp != null && bp.perm == p) {
9839                 bp.perm = null;
9840                 if (DEBUG_REMOVE && chatty) {
9841                     if (r == null) {
9842                         r = new StringBuilder(256);
9843                     } else {
9844                         r.append(' ');
9845                     }
9846                     r.append(p.info.name);
9847                 }
9848             }
9849             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9850                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
9851                 if (appOpPkgs != null) {
9852                     appOpPkgs.remove(pkg.packageName);
9853                 }
9854             }
9855         }
9856         if (r != null) {
9857             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9858         }
9859
9860         N = pkg.requestedPermissions.size();
9861         r = null;
9862         for (i=0; i<N; i++) {
9863             String perm = pkg.requestedPermissions.get(i);
9864             BasePermission bp = mSettings.mPermissions.get(perm);
9865             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9866                 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
9867                 if (appOpPkgs != null) {
9868                     appOpPkgs.remove(pkg.packageName);
9869                     if (appOpPkgs.isEmpty()) {
9870                         mAppOpPermissionPackages.remove(perm);
9871                     }
9872                 }
9873             }
9874         }
9875         if (r != null) {
9876             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9877         }
9878
9879         N = pkg.instrumentation.size();
9880         r = null;
9881         for (i=0; i<N; i++) {
9882             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
9883             mInstrumentation.remove(a.getComponentName());
9884             if (DEBUG_REMOVE && chatty) {
9885                 if (r == null) {
9886                     r = new StringBuilder(256);
9887                 } else {
9888                     r.append(' ');
9889                 }
9890                 r.append(a.info.name);
9891             }
9892         }
9893         if (r != null) {
9894             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
9895         }
9896
9897         r = null;
9898         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9899             // Only system apps can hold shared libraries.
9900             if (pkg.libraryNames != null) {
9901                 for (i=0; i<pkg.libraryNames.size(); i++) {
9902                     String name = pkg.libraryNames.get(i);
9903                     SharedLibraryEntry cur = mSharedLibraries.get(name);
9904                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
9905                         mSharedLibraries.remove(name);
9906                         if (DEBUG_REMOVE && chatty) {
9907                             if (r == null) {
9908                                 r = new StringBuilder(256);
9909                             } else {
9910                                 r.append(' ');
9911                             }
9912                             r.append(name);
9913                         }
9914                     }
9915                 }
9916             }
9917         }
9918         if (r != null) {
9919             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
9920         }
9921     }
9922
9923     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
9924         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
9925             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
9926                 return true;
9927             }
9928         }
9929         return false;
9930     }
9931
9932     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
9933     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
9934     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
9935
9936     private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
9937         // Update the parent permissions
9938         updatePermissionsLPw(pkg.packageName, pkg, flags);
9939         // Update the child permissions
9940         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9941         for (int i = 0; i < childCount; i++) {
9942             PackageParser.Package childPkg = pkg.childPackages.get(i);
9943             updatePermissionsLPw(childPkg.packageName, childPkg, flags);
9944         }
9945     }
9946
9947     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
9948             int flags) {
9949         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
9950         updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
9951     }
9952
9953     private void updatePermissionsLPw(String changingPkg,
9954             PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
9955         // Make sure there are no dangling permission trees.
9956         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
9957         while (it.hasNext()) {
9958             final BasePermission bp = it.next();
9959             if (bp.packageSetting == null) {
9960                 // We may not yet have parsed the package, so just see if
9961                 // we still know about its settings.
9962                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9963             }
9964             if (bp.packageSetting == null) {
9965                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
9966                         + " from package " + bp.sourcePackage);
9967                 it.remove();
9968             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9969                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
9970                     Slog.i(TAG, "Removing old permission tree: " + bp.name
9971                             + " from package " + bp.sourcePackage);
9972                     flags |= UPDATE_PERMISSIONS_ALL;
9973                     it.remove();
9974                 }
9975             }
9976         }
9977
9978         // Make sure all dynamic permissions have been assigned to a package,
9979         // and make sure there are no dangling permissions.
9980         it = mSettings.mPermissions.values().iterator();
9981         while (it.hasNext()) {
9982             final BasePermission bp = it.next();
9983             if (bp.type == BasePermission.TYPE_DYNAMIC) {
9984                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
9985                         + bp.name + " pkg=" + bp.sourcePackage
9986                         + " info=" + bp.pendingInfo);
9987                 if (bp.packageSetting == null && bp.pendingInfo != null) {
9988                     final BasePermission tree = findPermissionTreeLP(bp.name);
9989                     if (tree != null && tree.perm != null) {
9990                         bp.packageSetting = tree.packageSetting;
9991                         bp.perm = new PackageParser.Permission(tree.perm.owner,
9992                                 new PermissionInfo(bp.pendingInfo));
9993                         bp.perm.info.packageName = tree.perm.info.packageName;
9994                         bp.perm.info.name = bp.name;
9995                         bp.uid = tree.uid;
9996                     }
9997                 }
9998             }
9999             if (bp.packageSetting == null) {
10000                 // We may not yet have parsed the package, so just see if
10001                 // we still know about its settings.
10002                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
10003             }
10004             if (bp.packageSetting == null) {
10005                 Slog.w(TAG, "Removing dangling permission: " + bp.name
10006                         + " from package " + bp.sourcePackage);
10007                 it.remove();
10008             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
10009                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
10010                     Slog.i(TAG, "Removing old permission: " + bp.name
10011                             + " from package " + bp.sourcePackage);
10012                     flags |= UPDATE_PERMISSIONS_ALL;
10013                     it.remove();
10014                 }
10015             }
10016         }
10017
10018         // Now update the permissions for all packages, in particular
10019         // replace the granted permissions of the system packages.
10020         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
10021             for (PackageParser.Package pkg : mPackages.values()) {
10022                 if (pkg != pkgInfo) {
10023                     // Only replace for packages on requested volume
10024                     final String volumeUuid = getVolumeUuidForPackage(pkg);
10025                     final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
10026                             && Objects.equals(replaceVolumeUuid, volumeUuid);
10027                     grantPermissionsLPw(pkg, replace, changingPkg);
10028                 }
10029             }
10030         }
10031
10032         if (pkgInfo != null) {
10033             // Only replace for packages on requested volume
10034             final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
10035             final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
10036                     && Objects.equals(replaceVolumeUuid, volumeUuid);
10037             grantPermissionsLPw(pkgInfo, replace, changingPkg);
10038         }
10039     }
10040
10041     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
10042             String packageOfInterest) {
10043         // IMPORTANT: There are two types of permissions: install and runtime.
10044         // Install time permissions are granted when the app is installed to
10045         // all device users and users added in the future. Runtime permissions
10046         // are granted at runtime explicitly to specific users. Normal and signature
10047         // protected permissions are install time permissions. Dangerous permissions
10048         // are install permissions if the app's target SDK is Lollipop MR1 or older,
10049         // otherwise they are runtime permissions. This function does not manage
10050         // runtime permissions except for the case an app targeting Lollipop MR1
10051         // being upgraded to target a newer SDK, in which case dangerous permissions
10052         // are transformed from install time to runtime ones.
10053
10054         final PackageSetting ps = (PackageSetting) pkg.mExtras;
10055         if (ps == null) {
10056             return;
10057         }
10058
10059         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
10060
10061         PermissionsState permissionsState = ps.getPermissionsState();
10062         PermissionsState origPermissions = permissionsState;
10063
10064         final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
10065
10066         boolean runtimePermissionsRevoked = false;
10067         int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
10068
10069         boolean changedInstallPermission = false;
10070
10071         if (replace) {
10072             ps.installPermissionsFixed = false;
10073             if (!ps.isSharedUser()) {
10074                 origPermissions = new PermissionsState(permissionsState);
10075                 permissionsState.reset();
10076             } else {
10077                 // We need to know only about runtime permission changes since the
10078                 // calling code always writes the install permissions state but
10079                 // the runtime ones are written only if changed. The only cases of
10080                 // changed runtime permissions here are promotion of an install to
10081                 // runtime and revocation of a runtime from a shared user.
10082                 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
10083                         ps.sharedUser, UserManagerService.getInstance().getUserIds());
10084                 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
10085                     runtimePermissionsRevoked = true;
10086                 }
10087             }
10088         }
10089
10090         permissionsState.setGlobalGids(mGlobalGids);
10091
10092         final int N = pkg.requestedPermissions.size();
10093         for (int i=0; i<N; i++) {
10094             final String name = pkg.requestedPermissions.get(i);
10095             final BasePermission bp = mSettings.mPermissions.get(name);
10096
10097             if (DEBUG_INSTALL) {
10098                 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
10099             }
10100
10101             if (bp == null || bp.packageSetting == null) {
10102                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
10103                     Slog.w(TAG, "Unknown permission " + name
10104                             + " in package " + pkg.packageName);
10105                 }
10106                 continue;
10107             }
10108
10109             final String perm = bp.name;
10110             boolean allowedSig = false;
10111             int grant = GRANT_DENIED;
10112
10113             // Keep track of app op permissions.
10114             if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
10115                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
10116                 if (pkgs == null) {
10117                     pkgs = new ArraySet<>();
10118                     mAppOpPermissionPackages.put(bp.name, pkgs);
10119                 }
10120                 pkgs.add(pkg.packageName);
10121             }
10122
10123             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
10124             final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
10125                     >= Build.VERSION_CODES.M;
10126             switch (level) {
10127                 case PermissionInfo.PROTECTION_NORMAL: {
10128                     // For all apps normal permissions are install time ones.
10129                     grant = GRANT_INSTALL;
10130                 } break;
10131
10132                 case PermissionInfo.PROTECTION_DANGEROUS: {
10133                     // If a permission review is required for legacy apps we represent
10134                     // their permissions as always granted runtime ones since we need
10135                     // to keep the review required permission flag per user while an
10136                     // install permission's state is shared across all users.
10137                     if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) {
10138                         // For legacy apps dangerous permissions are install time ones.
10139                         grant = GRANT_INSTALL;
10140                     } else if (origPermissions.hasInstallPermission(bp.name)) {
10141                         // For legacy apps that became modern, install becomes runtime.
10142                         grant = GRANT_UPGRADE;
10143                     } else if (mPromoteSystemApps
10144                             && isSystemApp(ps)
10145                             && mExistingSystemPackages.contains(ps.name)) {
10146                         // For legacy system apps, install becomes runtime.
10147                         // We cannot check hasInstallPermission() for system apps since those
10148                         // permissions were granted implicitly and not persisted pre-M.
10149                         grant = GRANT_UPGRADE;
10150                     } else {
10151                         // For modern apps keep runtime permissions unchanged.
10152                         grant = GRANT_RUNTIME;
10153                     }
10154                 } break;
10155
10156                 case PermissionInfo.PROTECTION_SIGNATURE: {
10157                     // For all apps signature permissions are install time ones.
10158                     allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
10159                     if (allowedSig) {
10160                         grant = GRANT_INSTALL;
10161                     }
10162                 } break;
10163             }
10164
10165             if (DEBUG_INSTALL) {
10166                 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
10167             }
10168
10169             if (grant != GRANT_DENIED) {
10170                 if (!isSystemApp(ps) && ps.installPermissionsFixed) {
10171                     // If this is an existing, non-system package, then
10172                     // we can't add any new permissions to it.
10173                     if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
10174                         // Except...  if this is a permission that was added
10175                         // to the platform (note: need to only do this when
10176                         // updating the platform).
10177                         if (!isNewPlatformPermissionForPackage(perm, pkg)) {
10178                             grant = GRANT_DENIED;
10179                         }
10180                     }
10181                 }
10182
10183                 switch (grant) {
10184                     case GRANT_INSTALL: {
10185                         // Revoke this as runtime permission to handle the case of
10186                         // a runtime permission being downgraded to an install one.
10187                         // Also in permission review mode we keep dangerous permissions
10188                         // for legacy apps
10189                         for (int userId : UserManagerService.getInstance().getUserIds()) {
10190                             if (origPermissions.getRuntimePermissionState(
10191                                     bp.name, userId) != null) {
10192                                 // Revoke the runtime permission and clear the flags.
10193                                 origPermissions.revokeRuntimePermission(bp, userId);
10194                                 origPermissions.updatePermissionFlags(bp, userId,
10195                                       PackageManager.MASK_PERMISSION_FLAGS, 0);
10196                                 // If we revoked a permission permission, we have to write.
10197                                 changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10198                                         changedRuntimePermissionUserIds, userId);
10199                             }
10200                         }
10201                         // Grant an install permission.
10202                         if (permissionsState.grantInstallPermission(bp) !=
10203                                 PermissionsState.PERMISSION_OPERATION_FAILURE) {
10204                             changedInstallPermission = true;
10205                         }
10206                     } break;
10207
10208                     case GRANT_RUNTIME: {
10209                         // Grant previously granted runtime permissions.
10210                         for (int userId : UserManagerService.getInstance().getUserIds()) {
10211                             PermissionState permissionState = origPermissions
10212                                     .getRuntimePermissionState(bp.name, userId);
10213                             int flags = permissionState != null
10214                                     ? permissionState.getFlags() : 0;
10215                             if (origPermissions.hasRuntimePermission(bp.name, userId)) {
10216                                 if (permissionsState.grantRuntimePermission(bp, userId) ==
10217                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
10218                                     // If we cannot put the permission as it was, we have to write.
10219                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10220                                             changedRuntimePermissionUserIds, userId);
10221                                 }
10222                                 // If the app supports runtime permissions no need for a review.
10223                                 if (Build.PERMISSIONS_REVIEW_REQUIRED
10224                                         && appSupportsRuntimePermissions
10225                                         && (flags & PackageManager
10226                                                 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
10227                                     flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
10228                                     // Since we changed the flags, we have to write.
10229                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10230                                             changedRuntimePermissionUserIds, userId);
10231                                 }
10232                             } else if (Build.PERMISSIONS_REVIEW_REQUIRED
10233                                     && !appSupportsRuntimePermissions) {
10234                                 // For legacy apps that need a permission review, every new
10235                                 // runtime permission is granted but it is pending a review.
10236                                 // We also need to review only platform defined runtime
10237                                 // permissions as these are the only ones the platform knows
10238                                 // how to disable the API to simulate revocation as legacy
10239                                 // apps don't expect to run with revoked permissions.
10240                                 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
10241                                     if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
10242                                         flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
10243                                         // We changed the flags, hence have to write.
10244                                         changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10245                                                 changedRuntimePermissionUserIds, userId);
10246                                     }
10247                                 }
10248                                 if (permissionsState.grantRuntimePermission(bp, userId)
10249                                         != PermissionsState.PERMISSION_OPERATION_FAILURE) {
10250                                     // We changed the permission, hence have to write.
10251                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10252                                             changedRuntimePermissionUserIds, userId);
10253                                 }
10254                             }
10255                             // Propagate the permission flags.
10256                             permissionsState.updatePermissionFlags(bp, userId, flags, flags);
10257                         }
10258                     } break;
10259
10260                     case GRANT_UPGRADE: {
10261                         // Grant runtime permissions for a previously held install permission.
10262                         PermissionState permissionState = origPermissions
10263                                 .getInstallPermissionState(bp.name);
10264                         final int flags = permissionState != null ? permissionState.getFlags() : 0;
10265
10266                         if (origPermissions.revokeInstallPermission(bp)
10267                                 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
10268                             // We will be transferring the permission flags, so clear them.
10269                             origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
10270                                     PackageManager.MASK_PERMISSION_FLAGS, 0);
10271                             changedInstallPermission = true;
10272                         }
10273
10274                         // If the permission is not to be promoted to runtime we ignore it and
10275                         // also its other flags as they are not applicable to install permissions.
10276                         if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
10277                             for (int userId : currentUserIds) {
10278                                 if (permissionsState.grantRuntimePermission(bp, userId) !=
10279                                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
10280                                     // Transfer the permission flags.
10281                                     permissionsState.updatePermissionFlags(bp, userId,
10282                                             flags, flags);
10283                                     // If we granted the permission, we have to write.
10284                                     changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10285                                             changedRuntimePermissionUserIds, userId);
10286                                 }
10287                             }
10288                         }
10289                     } break;
10290
10291                     default: {
10292                         if (packageOfInterest == null
10293                                 || packageOfInterest.equals(pkg.packageName)) {
10294                             Slog.w(TAG, "Not granting permission " + perm
10295                                     + " to package " + pkg.packageName
10296                                     + " because it was previously installed without");
10297                         }
10298                     } break;
10299                 }
10300             } else {
10301                 if (permissionsState.revokeInstallPermission(bp) !=
10302                         PermissionsState.PERMISSION_OPERATION_FAILURE) {
10303                     // Also drop the permission flags.
10304                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
10305                             PackageManager.MASK_PERMISSION_FLAGS, 0);
10306                     changedInstallPermission = true;
10307                     Slog.i(TAG, "Un-granting permission " + perm
10308                             + " from package " + pkg.packageName
10309                             + " (protectionLevel=" + bp.protectionLevel
10310                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10311                             + ")");
10312                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
10313                     // Don't print warning for app op permissions, since it is fine for them
10314                     // not to be granted, there is a UI for the user to decide.
10315                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
10316                         Slog.w(TAG, "Not granting permission " + perm
10317                                 + " to package " + pkg.packageName
10318                                 + " (protectionLevel=" + bp.protectionLevel
10319                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10320                                 + ")");
10321                     }
10322                 }
10323             }
10324         }
10325
10326         if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
10327                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
10328             // This is the first that we have heard about this package, so the
10329             // permissions we have now selected are fixed until explicitly
10330             // changed.
10331             ps.installPermissionsFixed = true;
10332         }
10333
10334         // Persist the runtime permissions state for users with changes. If permissions
10335         // were revoked because no app in the shared user declares them we have to
10336         // write synchronously to avoid losing runtime permissions state.
10337         for (int userId : changedRuntimePermissionUserIds) {
10338             mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
10339         }
10340
10341         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10342     }
10343
10344     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
10345         boolean allowed = false;
10346         final int NP = PackageParser.NEW_PERMISSIONS.length;
10347         for (int ip=0; ip<NP; ip++) {
10348             final PackageParser.NewPermissionInfo npi
10349                     = PackageParser.NEW_PERMISSIONS[ip];
10350             if (npi.name.equals(perm)
10351                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
10352                 allowed = true;
10353                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
10354                         + pkg.packageName);
10355                 break;
10356             }
10357         }
10358         return allowed;
10359     }
10360
10361     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
10362             BasePermission bp, PermissionsState origPermissions) {
10363         boolean allowed;
10364         allowed = (compareSignatures(
10365                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
10366                         == PackageManager.SIGNATURE_MATCH)
10367                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
10368                         == PackageManager.SIGNATURE_MATCH);
10369         if (!allowed && (bp.protectionLevel
10370                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
10371             if (isSystemApp(pkg)) {
10372                 // For updated system applications, a system permission
10373                 // is granted only if it had been defined by the original application.
10374                 if (pkg.isUpdatedSystemApp()) {
10375                     final PackageSetting sysPs = mSettings
10376                             .getDisabledSystemPkgLPr(pkg.packageName);
10377                     if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
10378                         // If the original was granted this permission, we take
10379                         // that grant decision as read and propagate it to the
10380                         // update.
10381                         if (sysPs.isPrivileged()) {
10382                             allowed = true;
10383                         }
10384                     } else {
10385                         // The system apk may have been updated with an older
10386                         // version of the one on the data partition, but which
10387                         // granted a new system permission that it didn't have
10388                         // before.  In this case we do want to allow the app to
10389                         // now get the new permission if the ancestral apk is
10390                         // privileged to get it.
10391                         if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
10392                             for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
10393                                 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
10394                                     allowed = true;
10395                                     break;
10396                                 }
10397                             }
10398                         }
10399                         // Also if a privileged parent package on the system image or any of
10400                         // its children requested a privileged permission, the updated child
10401                         // packages can also get the permission.
10402                         if (pkg.parentPackage != null) {
10403                             final PackageSetting disabledSysParentPs = mSettings
10404                                     .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
10405                             if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
10406                                     && disabledSysParentPs.isPrivileged()) {
10407                                 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
10408                                     allowed = true;
10409                                 } else if (disabledSysParentPs.pkg.childPackages != null) {
10410                                     final int count = disabledSysParentPs.pkg.childPackages.size();
10411                                     for (int i = 0; i < count; i++) {
10412                                         PackageParser.Package disabledSysChildPkg =
10413                                                 disabledSysParentPs.pkg.childPackages.get(i);
10414                                         if (isPackageRequestingPermission(disabledSysChildPkg,
10415                                                 perm)) {
10416                                             allowed = true;
10417                                             break;
10418                                         }
10419                                     }
10420                                 }
10421                             }
10422                         }
10423                     }
10424                 } else {
10425                     allowed = isPrivilegedApp(pkg);
10426                 }
10427             }
10428         }
10429         if (!allowed) {
10430             if (!allowed && (bp.protectionLevel
10431                     & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
10432                     && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
10433                 // If this was a previously normal/dangerous permission that got moved
10434                 // to a system permission as part of the runtime permission redesign, then
10435                 // we still want to blindly grant it to old apps.
10436                 allowed = true;
10437             }
10438             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
10439                     && pkg.packageName.equals(mRequiredInstallerPackage)) {
10440                 // If this permission is to be granted to the system installer and
10441                 // this app is an installer, then it gets the permission.
10442                 allowed = true;
10443             }
10444             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
10445                     && pkg.packageName.equals(mRequiredVerifierPackage)) {
10446                 // If this permission is to be granted to the system verifier and
10447                 // this app is a verifier, then it gets the permission.
10448                 allowed = true;
10449             }
10450             if (!allowed && (bp.protectionLevel
10451                     & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
10452                     && isSystemApp(pkg)) {
10453                 // Any pre-installed system app is allowed to get this permission.
10454                 allowed = true;
10455             }
10456             if (!allowed && (bp.protectionLevel
10457                     & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
10458                 // For development permissions, a development permission
10459                 // is granted only if it was already granted.
10460                 allowed = origPermissions.hasInstallPermission(perm);
10461             }
10462             if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
10463                     && pkg.packageName.equals(mSetupWizardPackage)) {
10464                 // If this permission is to be granted to the system setup wizard and
10465                 // this app is a setup wizard, then it gets the permission.
10466                 allowed = true;
10467             }
10468         }
10469         return allowed;
10470     }
10471
10472     private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
10473         final int permCount = pkg.requestedPermissions.size();
10474         for (int j = 0; j < permCount; j++) {
10475             String requestedPermission = pkg.requestedPermissions.get(j);
10476             if (permission.equals(requestedPermission)) {
10477                 return true;
10478             }
10479         }
10480         return false;
10481     }
10482
10483     final class ActivityIntentResolver
10484             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
10485         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10486                 boolean defaultOnly, int userId) {
10487             if (!sUserManager.exists(userId)) return null;
10488             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10489             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10490         }
10491
10492         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10493                 int userId) {
10494             if (!sUserManager.exists(userId)) return null;
10495             mFlags = flags;
10496             return super.queryIntent(intent, resolvedType,
10497                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10498         }
10499
10500         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10501                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
10502             if (!sUserManager.exists(userId)) return null;
10503             if (packageActivities == null) {
10504                 return null;
10505             }
10506             mFlags = flags;
10507             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
10508             final int N = packageActivities.size();
10509             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
10510                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
10511
10512             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
10513             for (int i = 0; i < N; ++i) {
10514                 intentFilters = packageActivities.get(i).intents;
10515                 if (intentFilters != null && intentFilters.size() > 0) {
10516                     PackageParser.ActivityIntentInfo[] array =
10517                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
10518                     intentFilters.toArray(array);
10519                     listCut.add(array);
10520                 }
10521             }
10522             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
10523         }
10524
10525         /**
10526          * Finds a privileged activity that matches the specified activity names.
10527          */
10528         private PackageParser.Activity findMatchingActivity(
10529                 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
10530             for (PackageParser.Activity sysActivity : activityList) {
10531                 if (sysActivity.info.name.equals(activityInfo.name)) {
10532                     return sysActivity;
10533                 }
10534                 if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
10535                     return sysActivity;
10536                 }
10537                 if (sysActivity.info.targetActivity != null) {
10538                     if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
10539                         return sysActivity;
10540                     }
10541                     if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
10542                         return sysActivity;
10543                     }
10544                 }
10545             }
10546             return null;
10547         }
10548
10549         public class IterGenerator<E> {
10550             public Iterator<E> generate(ActivityIntentInfo info) {
10551                 return null;
10552             }
10553         }
10554
10555         public class ActionIterGenerator extends IterGenerator<String> {
10556             @Override
10557             public Iterator<String> generate(ActivityIntentInfo info) {
10558                 return info.actionsIterator();
10559             }
10560         }
10561
10562         public class CategoriesIterGenerator extends IterGenerator<String> {
10563             @Override
10564             public Iterator<String> generate(ActivityIntentInfo info) {
10565                 return info.categoriesIterator();
10566             }
10567         }
10568
10569         public class SchemesIterGenerator extends IterGenerator<String> {
10570             @Override
10571             public Iterator<String> generate(ActivityIntentInfo info) {
10572                 return info.schemesIterator();
10573             }
10574         }
10575
10576         public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
10577             @Override
10578             public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
10579                 return info.authoritiesIterator();
10580             }
10581         }
10582
10583         /**
10584          * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
10585          * MODIFIED. Do not pass in a list that should not be changed.
10586          */
10587         private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
10588                 IterGenerator<T> generator, Iterator<T> searchIterator) {
10589             // loop through the set of actions; every one must be found in the intent filter
10590             while (searchIterator.hasNext()) {
10591                 // we must have at least one filter in the list to consider a match
10592                 if (intentList.size() == 0) {
10593                     break;
10594                 }
10595
10596                 final T searchAction = searchIterator.next();
10597
10598                 // loop through the set of intent filters
10599                 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
10600                 while (intentIter.hasNext()) {
10601                     final ActivityIntentInfo intentInfo = intentIter.next();
10602                     boolean selectionFound = false;
10603
10604                     // loop through the intent filter's selection criteria; at least one
10605                     // of them must match the searched criteria
10606                     final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
10607                     while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
10608                         final T intentSelection = intentSelectionIter.next();
10609                         if (intentSelection != null && intentSelection.equals(searchAction)) {
10610                             selectionFound = true;
10611                             break;
10612                         }
10613                     }
10614
10615                     // the selection criteria wasn't found in this filter's set; this filter
10616                     // is not a potential match
10617                     if (!selectionFound) {
10618                         intentIter.remove();
10619                     }
10620                 }
10621             }
10622         }
10623
10624         private boolean isProtectedAction(ActivityIntentInfo filter) {
10625             final Iterator<String> actionsIter = filter.actionsIterator();
10626             while (actionsIter != null && actionsIter.hasNext()) {
10627                 final String filterAction = actionsIter.next();
10628                 if (PROTECTED_ACTIONS.contains(filterAction)) {
10629                     return true;
10630                 }
10631             }
10632             return false;
10633         }
10634
10635         /**
10636          * Adjusts the priority of the given intent filter according to policy.
10637          * <p>
10638          * <ul>
10639          * <li>The priority for non privileged applications is capped to '0'</li>
10640          * <li>The priority for protected actions on privileged applications is capped to '0'</li>
10641          * <li>The priority for unbundled updates to privileged applications is capped to the
10642          *      priority defined on the system partition</li>
10643          * </ul>
10644          * <p>
10645          * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
10646          * allowed to obtain any priority on any action.
10647          */
10648         private void adjustPriority(
10649                 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
10650             // nothing to do; priority is fine as-is
10651             if (intent.getPriority() <= 0) {
10652                 return;
10653             }
10654
10655             final ActivityInfo activityInfo = intent.activity.info;
10656             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
10657
10658             final boolean privilegedApp =
10659                     ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
10660             if (!privilegedApp) {
10661                 // non-privileged applications can never define a priority >0
10662                 Slog.w(TAG, "Non-privileged app; cap priority to 0;"
10663                         + " package: " + applicationInfo.packageName
10664                         + " activity: " + intent.activity.className
10665                         + " origPrio: " + intent.getPriority());
10666                 intent.setPriority(0);
10667                 return;
10668             }
10669
10670             if (systemActivities == null) {
10671                 // the system package is not disabled; we're parsing the system partition
10672                 if (isProtectedAction(intent)) {
10673                     if (mDeferProtectedFilters) {
10674                         // We can't deal with these just yet. No component should ever obtain a
10675                         // >0 priority for a protected actions, with ONE exception -- the setup
10676                         // wizard. The setup wizard, however, cannot be known until we're able to
10677                         // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
10678                         // until all intent filters have been processed. Chicken, meet egg.
10679                         // Let the filter temporarily have a high priority and rectify the
10680                         // priorities after all system packages have been scanned.
10681                         mProtectedFilters.add(intent);
10682                         if (DEBUG_FILTERS) {
10683                             Slog.i(TAG, "Protected action; save for later;"
10684                                     + " package: " + applicationInfo.packageName
10685                                     + " activity: " + intent.activity.className
10686                                     + " origPrio: " + intent.getPriority());
10687                         }
10688                         return;
10689                     } else {
10690                         if (DEBUG_FILTERS && mSetupWizardPackage == null) {
10691                             Slog.i(TAG, "No setup wizard;"
10692                                 + " All protected intents capped to priority 0");
10693                         }
10694                         if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
10695                             if (DEBUG_FILTERS) {
10696                                 Slog.i(TAG, "Found setup wizard;"
10697                                     + " allow priority " + intent.getPriority() + ";"
10698                                     + " package: " + intent.activity.info.packageName
10699                                     + " activity: " + intent.activity.className
10700                                     + " priority: " + intent.getPriority());
10701                             }
10702                             // setup wizard gets whatever it wants
10703                             return;
10704                         }
10705                         Slog.w(TAG, "Protected action; cap priority to 0;"
10706                                 + " package: " + intent.activity.info.packageName
10707                                 + " activity: " + intent.activity.className
10708                                 + " origPrio: " + intent.getPriority());
10709                         intent.setPriority(0);
10710                         return;
10711                     }
10712                 }
10713                 // privileged apps on the system image get whatever priority they request
10714                 return;
10715             }
10716
10717             // privileged app unbundled update ... try to find the same activity
10718             final PackageParser.Activity foundActivity =
10719                     findMatchingActivity(systemActivities, activityInfo);
10720             if (foundActivity == null) {
10721                 // this is a new activity; it cannot obtain >0 priority
10722                 if (DEBUG_FILTERS) {
10723                     Slog.i(TAG, "New activity; cap priority to 0;"
10724                             + " package: " + applicationInfo.packageName
10725                             + " activity: " + intent.activity.className
10726                             + " origPrio: " + intent.getPriority());
10727                 }
10728                 intent.setPriority(0);
10729                 return;
10730             }
10731
10732             // found activity, now check for filter equivalence
10733
10734             // a shallow copy is enough; we modify the list, not its contents
10735             final List<ActivityIntentInfo> intentListCopy =
10736                     new ArrayList<>(foundActivity.intents);
10737             final List<ActivityIntentInfo> foundFilters = findFilters(intent);
10738
10739             // find matching action subsets
10740             final Iterator<String> actionsIterator = intent.actionsIterator();
10741             if (actionsIterator != null) {
10742                 getIntentListSubset(
10743                         intentListCopy, new ActionIterGenerator(), actionsIterator);
10744                 if (intentListCopy.size() == 0) {
10745                     // no more intents to match; we're not equivalent
10746                     if (DEBUG_FILTERS) {
10747                         Slog.i(TAG, "Mismatched action; cap priority to 0;"
10748                                 + " package: " + applicationInfo.packageName
10749                                 + " activity: " + intent.activity.className
10750                                 + " origPrio: " + intent.getPriority());
10751                     }
10752                     intent.setPriority(0);
10753                     return;
10754                 }
10755             }
10756
10757             // find matching category subsets
10758             final Iterator<String> categoriesIterator = intent.categoriesIterator();
10759             if (categoriesIterator != null) {
10760                 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
10761                         categoriesIterator);
10762                 if (intentListCopy.size() == 0) {
10763                     // no more intents to match; we're not equivalent
10764                     if (DEBUG_FILTERS) {
10765                         Slog.i(TAG, "Mismatched category; cap priority to 0;"
10766                                 + " package: " + applicationInfo.packageName
10767                                 + " activity: " + intent.activity.className
10768                                 + " origPrio: " + intent.getPriority());
10769                     }
10770                     intent.setPriority(0);
10771                     return;
10772                 }
10773             }
10774
10775             // find matching schemes subsets
10776             final Iterator<String> schemesIterator = intent.schemesIterator();
10777             if (schemesIterator != null) {
10778                 getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
10779                         schemesIterator);
10780                 if (intentListCopy.size() == 0) {
10781                     // no more intents to match; we're not equivalent
10782                     if (DEBUG_FILTERS) {
10783                         Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
10784                                 + " package: " + applicationInfo.packageName
10785                                 + " activity: " + intent.activity.className
10786                                 + " origPrio: " + intent.getPriority());
10787                     }
10788                     intent.setPriority(0);
10789                     return;
10790                 }
10791             }
10792
10793             // find matching authorities subsets
10794             final Iterator<IntentFilter.AuthorityEntry>
10795                     authoritiesIterator = intent.authoritiesIterator();
10796             if (authoritiesIterator != null) {
10797                 getIntentListSubset(intentListCopy,
10798                         new AuthoritiesIterGenerator(),
10799                         authoritiesIterator);
10800                 if (intentListCopy.size() == 0) {
10801                     // no more intents to match; we're not equivalent
10802                     if (DEBUG_FILTERS) {
10803                         Slog.i(TAG, "Mismatched authority; cap priority to 0;"
10804                                 + " package: " + applicationInfo.packageName
10805                                 + " activity: " + intent.activity.className
10806                                 + " origPrio: " + intent.getPriority());
10807                     }
10808                     intent.setPriority(0);
10809                     return;
10810                 }
10811             }
10812
10813             // we found matching filter(s); app gets the max priority of all intents
10814             int cappedPriority = 0;
10815             for (int i = intentListCopy.size() - 1; i >= 0; --i) {
10816                 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
10817             }
10818             if (intent.getPriority() > cappedPriority) {
10819                 if (DEBUG_FILTERS) {
10820                     Slog.i(TAG, "Found matching filter(s);"
10821                             + " cap priority to " + cappedPriority + ";"
10822                             + " package: " + applicationInfo.packageName
10823                             + " activity: " + intent.activity.className
10824                             + " origPrio: " + intent.getPriority());
10825                 }
10826                 intent.setPriority(cappedPriority);
10827                 return;
10828             }
10829             // all this for nothing; the requested priority was <= what was on the system
10830         }
10831
10832         public final void addActivity(PackageParser.Activity a, String type) {
10833             mActivities.put(a.getComponentName(), a);
10834             if (DEBUG_SHOW_INFO)
10835                 Log.v(
10836                 TAG, "  " + type + " " +
10837                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
10838             if (DEBUG_SHOW_INFO)
10839                 Log.v(TAG, "    Class=" + a.info.name);
10840             final int NI = a.intents.size();
10841             for (int j=0; j<NI; j++) {
10842                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10843                 if ("activity".equals(type)) {
10844                     final PackageSetting ps =
10845                             mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
10846                     final List<PackageParser.Activity> systemActivities =
10847                             ps != null && ps.pkg != null ? ps.pkg.activities : null;
10848                     adjustPriority(systemActivities, intent);
10849                 }
10850                 if (DEBUG_SHOW_INFO) {
10851                     Log.v(TAG, "    IntentFilter:");
10852                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10853                 }
10854                 if (!intent.debugCheck()) {
10855                     Log.w(TAG, "==> For Activity " + a.info.name);
10856                 }
10857                 addFilter(intent);
10858             }
10859         }
10860
10861         public final void removeActivity(PackageParser.Activity a, String type) {
10862             mActivities.remove(a.getComponentName());
10863             if (DEBUG_SHOW_INFO) {
10864                 Log.v(TAG, "  " + type + " "
10865                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
10866                                 : a.info.name) + ":");
10867                 Log.v(TAG, "    Class=" + a.info.name);
10868             }
10869             final int NI = a.intents.size();
10870             for (int j=0; j<NI; j++) {
10871                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10872                 if (DEBUG_SHOW_INFO) {
10873                     Log.v(TAG, "    IntentFilter:");
10874                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10875                 }
10876                 removeFilter(intent);
10877             }
10878         }
10879
10880         @Override
10881         protected boolean allowFilterResult(
10882                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
10883             ActivityInfo filterAi = filter.activity.info;
10884             for (int i=dest.size()-1; i>=0; i--) {
10885                 ActivityInfo destAi = dest.get(i).activityInfo;
10886                 if (destAi.name == filterAi.name
10887                         && destAi.packageName == filterAi.packageName) {
10888                     return false;
10889                 }
10890             }
10891             return true;
10892         }
10893
10894         @Override
10895         protected ActivityIntentInfo[] newArray(int size) {
10896             return new ActivityIntentInfo[size];
10897         }
10898
10899         @Override
10900         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
10901             if (!sUserManager.exists(userId)) return true;
10902             PackageParser.Package p = filter.activity.owner;
10903             if (p != null) {
10904                 PackageSetting ps = (PackageSetting)p.mExtras;
10905                 if (ps != null) {
10906                     // System apps are never considered stopped for purposes of
10907                     // filtering, because there may be no way for the user to
10908                     // actually re-launch them.
10909                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
10910                             && ps.getStopped(userId);
10911                 }
10912             }
10913             return false;
10914         }
10915
10916         @Override
10917         protected boolean isPackageForFilter(String packageName,
10918                 PackageParser.ActivityIntentInfo info) {
10919             return packageName.equals(info.activity.owner.packageName);
10920         }
10921
10922         @Override
10923         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
10924                 int match, int userId) {
10925             if (!sUserManager.exists(userId)) return null;
10926             if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
10927                 return null;
10928             }
10929             final PackageParser.Activity activity = info.activity;
10930             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
10931             if (ps == null) {
10932                 return null;
10933             }
10934             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
10935                     ps.readUserState(userId), userId);
10936             if (ai == null) {
10937                 return null;
10938             }
10939             final ResolveInfo res = new ResolveInfo();
10940             res.activityInfo = ai;
10941             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
10942                 res.filter = info;
10943             }
10944             if (info != null) {
10945                 res.handleAllWebDataURI = info.handleAllWebDataURI();
10946             }
10947             res.priority = info.getPriority();
10948             res.preferredOrder = activity.owner.mPreferredOrder;
10949             //System.out.println("Result: " + res.activityInfo.className +
10950             //                   " = " + res.priority);
10951             res.match = match;
10952             res.isDefault = info.hasDefault;
10953             res.labelRes = info.labelRes;
10954             res.nonLocalizedLabel = info.nonLocalizedLabel;
10955             if (userNeedsBadging(userId)) {
10956                 res.noResourceId = true;
10957             } else {
10958                 res.icon = info.icon;
10959             }
10960             res.iconResourceId = info.icon;
10961             res.system = res.activityInfo.applicationInfo.isSystemApp();
10962             return res;
10963         }
10964
10965         @Override
10966         protected void sortResults(List<ResolveInfo> results) {
10967             Collections.sort(results, mResolvePrioritySorter);
10968         }
10969
10970         @Override
10971         protected void dumpFilter(PrintWriter out, String prefix,
10972                 PackageParser.ActivityIntentInfo filter) {
10973             out.print(prefix); out.print(
10974                     Integer.toHexString(System.identityHashCode(filter.activity)));
10975                     out.print(' ');
10976                     filter.activity.printComponentShortName(out);
10977                     out.print(" filter ");
10978                     out.println(Integer.toHexString(System.identityHashCode(filter)));
10979         }
10980
10981         @Override
10982         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
10983             return filter.activity;
10984         }
10985
10986         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
10987             PackageParser.Activity activity = (PackageParser.Activity)label;
10988             out.print(prefix); out.print(
10989                     Integer.toHexString(System.identityHashCode(activity)));
10990                     out.print(' ');
10991                     activity.printComponentShortName(out);
10992             if (count > 1) {
10993                 out.print(" ("); out.print(count); out.print(" filters)");
10994             }
10995             out.println();
10996         }
10997
10998         // Keys are String (activity class name), values are Activity.
10999         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
11000                 = new ArrayMap<ComponentName, PackageParser.Activity>();
11001         private int mFlags;
11002     }
11003
11004     private final class ServiceIntentResolver
11005             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
11006         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11007                 boolean defaultOnly, int userId) {
11008             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
11009             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11010         }
11011
11012         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11013                 int userId) {
11014             if (!sUserManager.exists(userId)) return null;
11015             mFlags = flags;
11016             return super.queryIntent(intent, resolvedType,
11017                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
11018         }
11019
11020         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11021                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
11022             if (!sUserManager.exists(userId)) return null;
11023             if (packageServices == null) {
11024                 return null;
11025             }
11026             mFlags = flags;
11027             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
11028             final int N = packageServices.size();
11029             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
11030                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
11031
11032             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
11033             for (int i = 0; i < N; ++i) {
11034                 intentFilters = packageServices.get(i).intents;
11035                 if (intentFilters != null && intentFilters.size() > 0) {
11036                     PackageParser.ServiceIntentInfo[] array =
11037                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
11038                     intentFilters.toArray(array);
11039                     listCut.add(array);
11040                 }
11041             }
11042             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11043         }
11044
11045         public final void addService(PackageParser.Service s) {
11046             mServices.put(s.getComponentName(), s);
11047             if (DEBUG_SHOW_INFO) {
11048                 Log.v(TAG, "  "
11049                         + (s.info.nonLocalizedLabel != null
11050                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
11051                 Log.v(TAG, "    Class=" + s.info.name);
11052             }
11053             final int NI = s.intents.size();
11054             int j;
11055             for (j=0; j<NI; j++) {
11056                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
11057                 if (DEBUG_SHOW_INFO) {
11058                     Log.v(TAG, "    IntentFilter:");
11059                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11060                 }
11061                 if (!intent.debugCheck()) {
11062                     Log.w(TAG, "==> For Service " + s.info.name);
11063                 }
11064                 addFilter(intent);
11065             }
11066         }
11067
11068         public final void removeService(PackageParser.Service s) {
11069             mServices.remove(s.getComponentName());
11070             if (DEBUG_SHOW_INFO) {
11071                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
11072                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
11073                 Log.v(TAG, "    Class=" + s.info.name);
11074             }
11075             final int NI = s.intents.size();
11076             int j;
11077             for (j=0; j<NI; j++) {
11078                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
11079                 if (DEBUG_SHOW_INFO) {
11080                     Log.v(TAG, "    IntentFilter:");
11081                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11082                 }
11083                 removeFilter(intent);
11084             }
11085         }
11086
11087         @Override
11088         protected boolean allowFilterResult(
11089                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
11090             ServiceInfo filterSi = filter.service.info;
11091             for (int i=dest.size()-1; i>=0; i--) {
11092                 ServiceInfo destAi = dest.get(i).serviceInfo;
11093                 if (destAi.name == filterSi.name
11094                         && destAi.packageName == filterSi.packageName) {
11095                     return false;
11096                 }
11097             }
11098             return true;
11099         }
11100
11101         @Override
11102         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
11103             return new PackageParser.ServiceIntentInfo[size];
11104         }
11105
11106         @Override
11107         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
11108             if (!sUserManager.exists(userId)) return true;
11109             PackageParser.Package p = filter.service.owner;
11110             if (p != null) {
11111                 PackageSetting ps = (PackageSetting)p.mExtras;
11112                 if (ps != null) {
11113                     // System apps are never considered stopped for purposes of
11114                     // filtering, because there may be no way for the user to
11115                     // actually re-launch them.
11116                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
11117                             && ps.getStopped(userId);
11118                 }
11119             }
11120             return false;
11121         }
11122
11123         @Override
11124         protected boolean isPackageForFilter(String packageName,
11125                 PackageParser.ServiceIntentInfo info) {
11126             return packageName.equals(info.service.owner.packageName);
11127         }
11128
11129         @Override
11130         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
11131                 int match, int userId) {
11132             if (!sUserManager.exists(userId)) return null;
11133             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
11134             if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
11135                 return null;
11136             }
11137             final PackageParser.Service service = info.service;
11138             PackageSetting ps = (PackageSetting) service.owner.mExtras;
11139             if (ps == null) {
11140                 return null;
11141             }
11142             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
11143                     ps.readUserState(userId), userId);
11144             if (si == null) {
11145                 return null;
11146             }
11147             final ResolveInfo res = new ResolveInfo();
11148             res.serviceInfo = si;
11149             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
11150                 res.filter = filter;
11151             }
11152             res.priority = info.getPriority();
11153             res.preferredOrder = service.owner.mPreferredOrder;
11154             res.match = match;
11155             res.isDefault = info.hasDefault;
11156             res.labelRes = info.labelRes;
11157             res.nonLocalizedLabel = info.nonLocalizedLabel;
11158             res.icon = info.icon;
11159             res.system = res.serviceInfo.applicationInfo.isSystemApp();
11160             return res;
11161         }
11162
11163         @Override
11164         protected void sortResults(List<ResolveInfo> results) {
11165             Collections.sort(results, mResolvePrioritySorter);
11166         }
11167
11168         @Override
11169         protected void dumpFilter(PrintWriter out, String prefix,
11170                 PackageParser.ServiceIntentInfo filter) {
11171             out.print(prefix); out.print(
11172                     Integer.toHexString(System.identityHashCode(filter.service)));
11173                     out.print(' ');
11174                     filter.service.printComponentShortName(out);
11175                     out.print(" filter ");
11176                     out.println(Integer.toHexString(System.identityHashCode(filter)));
11177         }
11178
11179         @Override
11180         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
11181             return filter.service;
11182         }
11183
11184         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11185             PackageParser.Service service = (PackageParser.Service)label;
11186             out.print(prefix); out.print(
11187                     Integer.toHexString(System.identityHashCode(service)));
11188                     out.print(' ');
11189                     service.printComponentShortName(out);
11190             if (count > 1) {
11191                 out.print(" ("); out.print(count); out.print(" filters)");
11192             }
11193             out.println();
11194         }
11195
11196 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
11197 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
11198 //            final List<ResolveInfo> retList = Lists.newArrayList();
11199 //            while (i.hasNext()) {
11200 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
11201 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
11202 //                    retList.add(resolveInfo);
11203 //                }
11204 //            }
11205 //            return retList;
11206 //        }
11207
11208         // Keys are String (activity class name), values are Activity.
11209         private final ArrayMap<ComponentName, PackageParser.Service> mServices
11210                 = new ArrayMap<ComponentName, PackageParser.Service>();
11211         private int mFlags;
11212     };
11213
11214     private final class ProviderIntentResolver
11215             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
11216         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11217                 boolean defaultOnly, int userId) {
11218             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
11219             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11220         }
11221
11222         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11223                 int userId) {
11224             if (!sUserManager.exists(userId))
11225                 return null;
11226             mFlags = flags;
11227             return super.queryIntent(intent, resolvedType,
11228                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
11229         }
11230
11231         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11232                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
11233             if (!sUserManager.exists(userId))
11234                 return null;
11235             if (packageProviders == null) {
11236                 return null;
11237             }
11238             mFlags = flags;
11239             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11240             final int N = packageProviders.size();
11241             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
11242                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
11243
11244             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
11245             for (int i = 0; i < N; ++i) {
11246                 intentFilters = packageProviders.get(i).intents;
11247                 if (intentFilters != null && intentFilters.size() > 0) {
11248                     PackageParser.ProviderIntentInfo[] array =
11249                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
11250                     intentFilters.toArray(array);
11251                     listCut.add(array);
11252                 }
11253             }
11254             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11255         }
11256
11257         public final void addProvider(PackageParser.Provider p) {
11258             if (mProviders.containsKey(p.getComponentName())) {
11259                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
11260                 return;
11261             }
11262
11263             mProviders.put(p.getComponentName(), p);
11264             if (DEBUG_SHOW_INFO) {
11265                 Log.v(TAG, "  "
11266                         + (p.info.nonLocalizedLabel != null
11267                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
11268                 Log.v(TAG, "    Class=" + p.info.name);
11269             }
11270             final int NI = p.intents.size();
11271             int j;
11272             for (j = 0; j < NI; j++) {
11273                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11274                 if (DEBUG_SHOW_INFO) {
11275                     Log.v(TAG, "    IntentFilter:");
11276                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11277                 }
11278                 if (!intent.debugCheck()) {
11279                     Log.w(TAG, "==> For Provider " + p.info.name);
11280                 }
11281                 addFilter(intent);
11282             }
11283         }
11284
11285         public final void removeProvider(PackageParser.Provider p) {
11286             mProviders.remove(p.getComponentName());
11287             if (DEBUG_SHOW_INFO) {
11288                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
11289                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
11290                 Log.v(TAG, "    Class=" + p.info.name);
11291             }
11292             final int NI = p.intents.size();
11293             int j;
11294             for (j = 0; j < NI; j++) {
11295                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11296                 if (DEBUG_SHOW_INFO) {
11297                     Log.v(TAG, "    IntentFilter:");
11298                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11299                 }
11300                 removeFilter(intent);
11301             }
11302         }
11303
11304         @Override
11305         protected boolean allowFilterResult(
11306                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
11307             ProviderInfo filterPi = filter.provider.info;
11308             for (int i = dest.size() - 1; i >= 0; i--) {
11309                 ProviderInfo destPi = dest.get(i).providerInfo;
11310                 if (destPi.name == filterPi.name
11311                         && destPi.packageName == filterPi.packageName) {
11312                     return false;
11313                 }
11314             }
11315             return true;
11316         }
11317
11318         @Override
11319         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
11320             return new PackageParser.ProviderIntentInfo[size];
11321         }
11322
11323         @Override
11324         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
11325             if (!sUserManager.exists(userId))
11326                 return true;
11327             PackageParser.Package p = filter.provider.owner;
11328             if (p != null) {
11329                 PackageSetting ps = (PackageSetting) p.mExtras;
11330                 if (ps != null) {
11331                     // System apps are never considered stopped for purposes of
11332                     // filtering, because there may be no way for the user to
11333                     // actually re-launch them.
11334                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
11335                             && ps.getStopped(userId);
11336                 }
11337             }
11338             return false;
11339         }
11340
11341         @Override
11342         protected boolean isPackageForFilter(String packageName,
11343                 PackageParser.ProviderIntentInfo info) {
11344             return packageName.equals(info.provider.owner.packageName);
11345         }
11346
11347         @Override
11348         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
11349                 int match, int userId) {
11350             if (!sUserManager.exists(userId))
11351                 return null;
11352             final PackageParser.ProviderIntentInfo info = filter;
11353             if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
11354                 return null;
11355             }
11356             final PackageParser.Provider provider = info.provider;
11357             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
11358             if (ps == null) {
11359                 return null;
11360             }
11361             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
11362                     ps.readUserState(userId), userId);
11363             if (pi == null) {
11364                 return null;
11365             }
11366             final ResolveInfo res = new ResolveInfo();
11367             res.providerInfo = pi;
11368             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
11369                 res.filter = filter;
11370             }
11371             res.priority = info.getPriority();
11372             res.preferredOrder = provider.owner.mPreferredOrder;
11373             res.match = match;
11374             res.isDefault = info.hasDefault;
11375             res.labelRes = info.labelRes;
11376             res.nonLocalizedLabel = info.nonLocalizedLabel;
11377             res.icon = info.icon;
11378             res.system = res.providerInfo.applicationInfo.isSystemApp();
11379             return res;
11380         }
11381
11382         @Override
11383         protected void sortResults(List<ResolveInfo> results) {
11384             Collections.sort(results, mResolvePrioritySorter);
11385         }
11386
11387         @Override
11388         protected void dumpFilter(PrintWriter out, String prefix,
11389                 PackageParser.ProviderIntentInfo filter) {
11390             out.print(prefix);
11391             out.print(
11392                     Integer.toHexString(System.identityHashCode(filter.provider)));
11393             out.print(' ');
11394             filter.provider.printComponentShortName(out);
11395             out.print(" filter ");
11396             out.println(Integer.toHexString(System.identityHashCode(filter)));
11397         }
11398
11399         @Override
11400         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
11401             return filter.provider;
11402         }
11403
11404         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11405             PackageParser.Provider provider = (PackageParser.Provider)label;
11406             out.print(prefix); out.print(
11407                     Integer.toHexString(System.identityHashCode(provider)));
11408                     out.print(' ');
11409                     provider.printComponentShortName(out);
11410             if (count > 1) {
11411                 out.print(" ("); out.print(count); out.print(" filters)");
11412             }
11413             out.println();
11414         }
11415
11416         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
11417                 = new ArrayMap<ComponentName, PackageParser.Provider>();
11418         private int mFlags;
11419     }
11420
11421     private static final class EphemeralIntentResolver
11422             extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
11423         /**
11424          * The result that has the highest defined order. Ordering applies on a
11425          * per-package basis. Mapping is from package name to Pair of order and
11426          * EphemeralResolveInfo.
11427          * <p>
11428          * NOTE: This is implemented as a field variable for convenience and efficiency.
11429          * By having a field variable, we're able to track filter ordering as soon as
11430          * a non-zero order is defined. Otherwise, multiple loops across the result set
11431          * would be needed to apply ordering. If the intent resolver becomes re-entrant,
11432          * this needs to be contained entirely within {@link #filterResults()}.
11433          */
11434         final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
11435
11436         @Override
11437         protected EphemeralResolveIntentInfo[] newArray(int size) {
11438             return new EphemeralResolveIntentInfo[size];
11439         }
11440
11441         @Override
11442         protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
11443             return true;
11444         }
11445
11446         @Override
11447         protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
11448                 int userId) {
11449             if (!sUserManager.exists(userId)) {
11450                 return null;
11451             }
11452             final String packageName = info.getEphemeralResolveInfo().getPackageName();
11453             final Integer order = info.getOrder();
11454             final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
11455                     mOrderResult.get(packageName);
11456             // ordering is enabled and this item's order isn't high enough
11457             if (lastOrderResult != null && lastOrderResult.first >= order) {
11458                 return null;
11459             }
11460             final EphemeralResolveInfo res = info.getEphemeralResolveInfo();
11461             if (order > 0) {
11462                 // non-zero order, enable ordering
11463                 mOrderResult.put(packageName, new Pair<>(order, res));
11464             }
11465             return res;
11466         }
11467
11468         @Override
11469         protected void filterResults(List<EphemeralResolveInfo> results) {
11470             // only do work if ordering is enabled [most of the time it won't be]
11471             if (mOrderResult.size() == 0) {
11472                 return;
11473             }
11474             int resultSize = results.size();
11475             for (int i = 0; i < resultSize; i++) {
11476                 final EphemeralResolveInfo info = results.get(i);
11477                 final String packageName = info.getPackageName();
11478                 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
11479                 if (savedInfo == null) {
11480                     // package doesn't having ordering
11481                     continue;
11482                 }
11483                 if (savedInfo.second == info) {
11484                     // circled back to the highest ordered item; remove from order list
11485                     mOrderResult.remove(savedInfo);
11486                     if (mOrderResult.size() == 0) {
11487                         // no more ordered items
11488                         break;
11489                     }
11490                     continue;
11491                 }
11492                 // item has a worse order, remove it from the result list
11493                 results.remove(i);
11494                 resultSize--;
11495                 i--;
11496             }
11497         }
11498     }
11499
11500     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
11501             new Comparator<ResolveInfo>() {
11502         public int compare(ResolveInfo r1, ResolveInfo r2) {
11503             int v1 = r1.priority;
11504             int v2 = r2.priority;
11505             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
11506             if (v1 != v2) {
11507                 return (v1 > v2) ? -1 : 1;
11508             }
11509             v1 = r1.preferredOrder;
11510             v2 = r2.preferredOrder;
11511             if (v1 != v2) {
11512                 return (v1 > v2) ? -1 : 1;
11513             }
11514             if (r1.isDefault != r2.isDefault) {
11515                 return r1.isDefault ? -1 : 1;
11516             }
11517             v1 = r1.match;
11518             v2 = r2.match;
11519             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
11520             if (v1 != v2) {
11521                 return (v1 > v2) ? -1 : 1;
11522             }
11523             if (r1.system != r2.system) {
11524                 return r1.system ? -1 : 1;
11525             }
11526             if (r1.activityInfo != null) {
11527                 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
11528             }
11529             if (r1.serviceInfo != null) {
11530                 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
11531             }
11532             if (r1.providerInfo != null) {
11533                 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
11534             }
11535             return 0;
11536         }
11537     };
11538
11539     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
11540             new Comparator<ProviderInfo>() {
11541         public int compare(ProviderInfo p1, ProviderInfo p2) {
11542             final int v1 = p1.initOrder;
11543             final int v2 = p2.initOrder;
11544             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
11545         }
11546     };
11547
11548     final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
11549             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
11550             final int[] userIds) {
11551         mHandler.post(new Runnable() {
11552             @Override
11553             public void run() {
11554                 try {
11555                     final IActivityManager am = ActivityManagerNative.getDefault();
11556                     if (am == null) return;
11557                     final int[] resolvedUserIds;
11558                     if (userIds == null) {
11559                         resolvedUserIds = am.getRunningUserIds();
11560                     } else {
11561                         resolvedUserIds = userIds;
11562                     }
11563                     for (int id : resolvedUserIds) {
11564                         final Intent intent = new Intent(action,
11565                                 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
11566                         if (extras != null) {
11567                             intent.putExtras(extras);
11568                         }
11569                         if (targetPkg != null) {
11570                             intent.setPackage(targetPkg);
11571                         }
11572                         // Modify the UID when posting to other users
11573                         int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
11574                         if (uid > 0 && UserHandle.getUserId(uid) != id) {
11575                             uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
11576                             intent.putExtra(Intent.EXTRA_UID, uid);
11577                         }
11578                         intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
11579                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
11580                         if (DEBUG_BROADCASTS) {
11581                             RuntimeException here = new RuntimeException("here");
11582                             here.fillInStackTrace();
11583                             Slog.d(TAG, "Sending to user " + id + ": "
11584                                     + intent.toShortString(false, true, false, false)
11585                                     + " " + intent.getExtras(), here);
11586                         }
11587                         am.broadcastIntent(null, intent, null, finishedReceiver,
11588                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
11589                                 null, finishedReceiver != null, false, id);
11590                     }
11591                 } catch (RemoteException ex) {
11592                 }
11593             }
11594         });
11595     }
11596
11597     /**
11598      * Check if the external storage media is available. This is true if there
11599      * is a mounted external storage medium or if the external storage is
11600      * emulated.
11601      */
11602     private boolean isExternalMediaAvailable() {
11603         return mMediaMounted || Environment.isExternalStorageEmulated();
11604     }
11605
11606     @Override
11607     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
11608         // writer
11609         synchronized (mPackages) {
11610             if (!isExternalMediaAvailable()) {
11611                 // If the external storage is no longer mounted at this point,
11612                 // the caller may not have been able to delete all of this
11613                 // packages files and can not delete any more.  Bail.
11614                 return null;
11615             }
11616             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
11617             if (lastPackage != null) {
11618                 pkgs.remove(lastPackage);
11619             }
11620             if (pkgs.size() > 0) {
11621                 return pkgs.get(0);
11622             }
11623         }
11624         return null;
11625     }
11626
11627     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
11628         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
11629                 userId, andCode ? 1 : 0, packageName);
11630         if (mSystemReady) {
11631             msg.sendToTarget();
11632         } else {
11633             if (mPostSystemReadyMessages == null) {
11634                 mPostSystemReadyMessages = new ArrayList<>();
11635             }
11636             mPostSystemReadyMessages.add(msg);
11637         }
11638     }
11639
11640     void startCleaningPackages() {
11641         // reader
11642         if (!isExternalMediaAvailable()) {
11643             return;
11644         }
11645         synchronized (mPackages) {
11646             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
11647                 return;
11648             }
11649         }
11650         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
11651         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
11652         IActivityManager am = ActivityManagerNative.getDefault();
11653         if (am != null) {
11654             try {
11655                 am.startService(null, intent, null, mContext.getOpPackageName(),
11656                         UserHandle.USER_SYSTEM);
11657             } catch (RemoteException e) {
11658             }
11659         }
11660     }
11661
11662     @Override
11663     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
11664             int installFlags, String installerPackageName, int userId) {
11665         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
11666
11667         final int callingUid = Binder.getCallingUid();
11668         enforceCrossUserPermission(callingUid, userId,
11669                 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
11670
11671         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11672             try {
11673                 if (observer != null) {
11674                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
11675                 }
11676             } catch (RemoteException re) {
11677             }
11678             return;
11679         }
11680
11681         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
11682             installFlags |= PackageManager.INSTALL_FROM_ADB;
11683
11684         } else {
11685             // Caller holds INSTALL_PACKAGES permission, so we're less strict
11686             // about installerPackageName.
11687
11688             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
11689             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
11690         }
11691
11692         UserHandle user;
11693         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
11694             user = UserHandle.ALL;
11695         } else {
11696             user = new UserHandle(userId);
11697         }
11698
11699         // Only system components can circumvent runtime permissions when installing.
11700         if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
11701                 && mContext.checkCallingOrSelfPermission(Manifest.permission
11702                 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
11703             throw new SecurityException("You need the "
11704                     + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
11705                     + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
11706         }
11707
11708         final File originFile = new File(originPath);
11709         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
11710
11711         final Message msg = mHandler.obtainMessage(INIT_COPY);
11712         final VerificationInfo verificationInfo = new VerificationInfo(
11713                 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
11714         final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
11715                 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
11716                 null /*packageAbiOverride*/, null /*grantedPermissions*/,
11717                 null /*certificates*/);
11718         params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
11719         msg.obj = params;
11720
11721         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
11722                 System.identityHashCode(msg.obj));
11723         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11724                 System.identityHashCode(msg.obj));
11725
11726         mHandler.sendMessage(msg);
11727     }
11728
11729     void installStage(String packageName, File stagedDir, String stagedCid,
11730             IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
11731             String installerPackageName, int installerUid, UserHandle user,
11732             Certificate[][] certificates) {
11733         if (DEBUG_EPHEMERAL) {
11734             if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
11735                 Slog.d(TAG, "Ephemeral install of " + packageName);
11736             }
11737         }
11738         final VerificationInfo verificationInfo = new VerificationInfo(
11739                 sessionParams.originatingUri, sessionParams.referrerUri,
11740                 sessionParams.originatingUid, installerUid);
11741
11742         final OriginInfo origin;
11743         if (stagedDir != null) {
11744             origin = OriginInfo.fromStagedFile(stagedDir);
11745         } else {
11746             origin = OriginInfo.fromStagedContainer(stagedCid);
11747         }
11748
11749         final Message msg = mHandler.obtainMessage(INIT_COPY);
11750         final InstallParams params = new InstallParams(origin, null, observer,
11751                 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
11752                 verificationInfo, user, sessionParams.abiOverride,
11753                 sessionParams.grantedRuntimePermissions, certificates);
11754         params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
11755         msg.obj = params;
11756
11757         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
11758                 System.identityHashCode(msg.obj));
11759         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11760                 System.identityHashCode(msg.obj));
11761
11762         mHandler.sendMessage(msg);
11763     }
11764
11765     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
11766             int userId) {
11767         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
11768         sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
11769     }
11770
11771     private void sendPackageAddedForUser(String packageName, boolean isSystem,
11772             int appId, int userId) {
11773         Bundle extras = new Bundle(1);
11774         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
11775
11776         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
11777                 packageName, extras, 0, null, null, new int[] {userId});
11778         try {
11779             IActivityManager am = ActivityManagerNative.getDefault();
11780             if (isSystem && am.isUserRunning(userId, 0)) {
11781                 // The just-installed/enabled app is bundled on the system, so presumed
11782                 // to be able to run automatically without needing an explicit launch.
11783                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
11784                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
11785                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
11786                         .setPackage(packageName);
11787                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
11788                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
11789             }
11790         } catch (RemoteException e) {
11791             // shouldn't happen
11792             Slog.w(TAG, "Unable to bootstrap installed package", e);
11793         }
11794     }
11795
11796     @Override
11797     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
11798             int userId) {
11799         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11800         PackageSetting pkgSetting;
11801         final int uid = Binder.getCallingUid();
11802         enforceCrossUserPermission(uid, userId,
11803                 true /* requireFullPermission */, true /* checkShell */,
11804                 "setApplicationHiddenSetting for user " + userId);
11805
11806         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
11807             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
11808             return false;
11809         }
11810
11811         long callingId = Binder.clearCallingIdentity();
11812         try {
11813             boolean sendAdded = false;
11814             boolean sendRemoved = false;
11815             // writer
11816             synchronized (mPackages) {
11817                 pkgSetting = mSettings.mPackages.get(packageName);
11818                 if (pkgSetting == null) {
11819                     return false;
11820                 }
11821                 // Do not allow "android" is being disabled
11822                 if ("android".equals(packageName)) {
11823                     Slog.w(TAG, "Cannot hide package: android");
11824                     return false;
11825                 }
11826                 // Only allow protected packages to hide themselves.
11827                 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
11828                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
11829                     Slog.w(TAG, "Not hiding protected package: " + packageName);
11830                     return false;
11831                 }
11832
11833                 if (pkgSetting.getHidden(userId) != hidden) {
11834                     pkgSetting.setHidden(hidden, userId);
11835                     mSettings.writePackageRestrictionsLPr(userId);
11836                     if (hidden) {
11837                         sendRemoved = true;
11838                     } else {
11839                         sendAdded = true;
11840                     }
11841                 }
11842             }
11843             if (sendAdded) {
11844                 sendPackageAddedForUser(packageName, pkgSetting, userId);
11845                 return true;
11846             }
11847             if (sendRemoved) {
11848                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
11849                         "hiding pkg");
11850                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
11851                 return true;
11852             }
11853         } finally {
11854             Binder.restoreCallingIdentity(callingId);
11855         }
11856         return false;
11857     }
11858
11859     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
11860             int userId) {
11861         final PackageRemovedInfo info = new PackageRemovedInfo();
11862         info.removedPackage = packageName;
11863         info.removedUsers = new int[] {userId};
11864         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
11865         info.sendPackageRemovedBroadcasts(true /*killApp*/);
11866     }
11867
11868     private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
11869         if (pkgList.length > 0) {
11870             Bundle extras = new Bundle(1);
11871             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
11872
11873             sendPackageBroadcast(
11874                     suspended ? Intent.ACTION_PACKAGES_SUSPENDED
11875                             : Intent.ACTION_PACKAGES_UNSUSPENDED,
11876                     null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
11877                     new int[] {userId});
11878         }
11879     }
11880
11881     /**
11882      * Returns true if application is not found or there was an error. Otherwise it returns
11883      * the hidden state of the package for the given user.
11884      */
11885     @Override
11886     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
11887         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11888         enforceCrossUserPermission(Binder.getCallingUid(), userId,
11889                 true /* requireFullPermission */, false /* checkShell */,
11890                 "getApplicationHidden for user " + userId);
11891         PackageSetting pkgSetting;
11892         long callingId = Binder.clearCallingIdentity();
11893         try {
11894             // writer
11895             synchronized (mPackages) {
11896                 pkgSetting = mSettings.mPackages.get(packageName);
11897                 if (pkgSetting == null) {
11898                     return true;
11899                 }
11900                 return pkgSetting.getHidden(userId);
11901             }
11902         } finally {
11903             Binder.restoreCallingIdentity(callingId);
11904         }
11905     }
11906
11907     /**
11908      * @hide
11909      */
11910     @Override
11911     public int installExistingPackageAsUser(String packageName, int userId) {
11912         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
11913                 null);
11914         PackageSetting pkgSetting;
11915         final int uid = Binder.getCallingUid();
11916         enforceCrossUserPermission(uid, userId,
11917                 true /* requireFullPermission */, true /* checkShell */,
11918                 "installExistingPackage for user " + userId);
11919         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11920             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
11921         }
11922
11923         long callingId = Binder.clearCallingIdentity();
11924         try {
11925             boolean installed = false;
11926
11927             // writer
11928             synchronized (mPackages) {
11929                 pkgSetting = mSettings.mPackages.get(packageName);
11930                 if (pkgSetting == null) {
11931                     return PackageManager.INSTALL_FAILED_INVALID_URI;
11932                 }
11933                 if (!pkgSetting.getInstalled(userId)) {
11934                     pkgSetting.setInstalled(true, userId);
11935                     pkgSetting.setHidden(false, userId);
11936                     mSettings.writePackageRestrictionsLPr(userId);
11937                     installed = true;
11938                 }
11939             }
11940
11941             if (installed) {
11942                 if (pkgSetting.pkg != null) {
11943                     synchronized (mInstallLock) {
11944                         // We don't need to freeze for a brand new install
11945                         prepareAppDataAfterInstallLIF(pkgSetting.pkg);
11946                     }
11947                 }
11948                 sendPackageAddedForUser(packageName, pkgSetting, userId);
11949             }
11950         } finally {
11951             Binder.restoreCallingIdentity(callingId);
11952         }
11953
11954         return PackageManager.INSTALL_SUCCEEDED;
11955     }
11956
11957     boolean isUserRestricted(int userId, String restrictionKey) {
11958         Bundle restrictions = sUserManager.getUserRestrictions(userId);
11959         if (restrictions.getBoolean(restrictionKey, false)) {
11960             Log.w(TAG, "User is restricted: " + restrictionKey);
11961             return true;
11962         }
11963         return false;
11964     }
11965
11966     @Override
11967     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
11968             int userId) {
11969         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11970         enforceCrossUserPermission(Binder.getCallingUid(), userId,
11971                 true /* requireFullPermission */, true /* checkShell */,
11972                 "setPackagesSuspended for user " + userId);
11973
11974         if (ArrayUtils.isEmpty(packageNames)) {
11975             return packageNames;
11976         }
11977
11978         // List of package names for whom the suspended state has changed.
11979         List<String> changedPackages = new ArrayList<>(packageNames.length);
11980         // List of package names for whom the suspended state is not set as requested in this
11981         // method.
11982         List<String> unactionedPackages = new ArrayList<>(packageNames.length);
11983         long callingId = Binder.clearCallingIdentity();
11984         try {
11985             for (int i = 0; i < packageNames.length; i++) {
11986                 String packageName = packageNames[i];
11987                 boolean changed = false;
11988                 final int appId;
11989                 synchronized (mPackages) {
11990                     final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
11991                     if (pkgSetting == null) {
11992                         Slog.w(TAG, "Could not find package setting for package \"" + packageName
11993                                 + "\". Skipping suspending/un-suspending.");
11994                         unactionedPackages.add(packageName);
11995                         continue;
11996                     }
11997                     appId = pkgSetting.appId;
11998                     if (pkgSetting.getSuspended(userId) != suspended) {
11999                         if (!canSuspendPackageForUserLocked(packageName, userId)) {
12000                             unactionedPackages.add(packageName);
12001                             continue;
12002                         }
12003                         pkgSetting.setSuspended(suspended, userId);
12004                         mSettings.writePackageRestrictionsLPr(userId);
12005                         changed = true;
12006                         changedPackages.add(packageName);
12007                     }
12008                 }
12009
12010                 if (changed && suspended) {
12011                     killApplication(packageName, UserHandle.getUid(userId, appId),
12012                             "suspending package");
12013                 }
12014             }
12015         } finally {
12016             Binder.restoreCallingIdentity(callingId);
12017         }
12018
12019         if (!changedPackages.isEmpty()) {
12020             sendPackagesSuspendedForUser(changedPackages.toArray(
12021                     new String[changedPackages.size()]), userId, suspended);
12022         }
12023
12024         return unactionedPackages.toArray(new String[unactionedPackages.size()]);
12025     }
12026
12027     @Override
12028     public boolean isPackageSuspendedForUser(String packageName, int userId) {
12029         enforceCrossUserPermission(Binder.getCallingUid(), userId,
12030                 true /* requireFullPermission */, false /* checkShell */,
12031                 "isPackageSuspendedForUser for user " + userId);
12032         synchronized (mPackages) {
12033             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
12034             if (pkgSetting == null) {
12035                 throw new IllegalArgumentException("Unknown target package: " + packageName);
12036             }
12037             return pkgSetting.getSuspended(userId);
12038         }
12039     }
12040
12041     private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
12042         if (isPackageDeviceAdmin(packageName, userId)) {
12043             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12044                     + "\": has an active device admin");
12045             return false;
12046         }
12047
12048         String activeLauncherPackageName = getActiveLauncherPackageName(userId);
12049         if (packageName.equals(activeLauncherPackageName)) {
12050             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12051                     + "\": contains the active launcher");
12052             return false;
12053         }
12054
12055         if (packageName.equals(mRequiredInstallerPackage)) {
12056             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12057                     + "\": required for package installation");
12058             return false;
12059         }
12060
12061         if (packageName.equals(mRequiredUninstallerPackage)) {
12062             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12063                     + "\": required for package uninstallation");
12064             return false;
12065         }
12066
12067         if (packageName.equals(mRequiredVerifierPackage)) {
12068             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12069                     + "\": required for package verification");
12070             return false;
12071         }
12072
12073         if (packageName.equals(getDefaultDialerPackageName(userId))) {
12074             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12075                     + "\": is the default dialer");
12076             return false;
12077         }
12078
12079         if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
12080             Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
12081                     + "\": protected package");
12082             return false;
12083         }
12084
12085         return true;
12086     }
12087
12088     private String getActiveLauncherPackageName(int userId) {
12089         Intent intent = new Intent(Intent.ACTION_MAIN);
12090         intent.addCategory(Intent.CATEGORY_HOME);
12091         ResolveInfo resolveInfo = resolveIntent(
12092                 intent,
12093                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
12094                 PackageManager.MATCH_DEFAULT_ONLY,
12095                 userId);
12096
12097         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
12098     }
12099
12100     private String getDefaultDialerPackageName(int userId) {
12101         synchronized (mPackages) {
12102             return mSettings.getDefaultDialerPackageNameLPw(userId);
12103         }
12104     }
12105
12106     @Override
12107     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
12108         mContext.enforceCallingOrSelfPermission(
12109                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12110                 "Only package verification agents can verify applications");
12111
12112         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
12113         final PackageVerificationResponse response = new PackageVerificationResponse(
12114                 verificationCode, Binder.getCallingUid());
12115         msg.arg1 = id;
12116         msg.obj = response;
12117         mHandler.sendMessage(msg);
12118     }
12119
12120     @Override
12121     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
12122             long millisecondsToDelay) {
12123         mContext.enforceCallingOrSelfPermission(
12124                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12125                 "Only package verification agents can extend verification timeouts");
12126
12127         final PackageVerificationState state = mPendingVerification.get(id);
12128         final PackageVerificationResponse response = new PackageVerificationResponse(
12129                 verificationCodeAtTimeout, Binder.getCallingUid());
12130
12131         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
12132             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
12133         }
12134         if (millisecondsToDelay < 0) {
12135             millisecondsToDelay = 0;
12136         }
12137         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
12138                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
12139             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
12140         }
12141
12142         if ((state != null) && !state.timeoutExtended()) {
12143             state.extendTimeout();
12144
12145             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
12146             msg.arg1 = id;
12147             msg.obj = response;
12148             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
12149         }
12150     }
12151
12152     private void broadcastPackageVerified(int verificationId, Uri packageUri,
12153             int verificationCode, UserHandle user) {
12154         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
12155         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
12156         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
12157         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
12158         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
12159
12160         mContext.sendBroadcastAsUser(intent, user,
12161                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
12162     }
12163
12164     private ComponentName matchComponentForVerifier(String packageName,
12165             List<ResolveInfo> receivers) {
12166         ActivityInfo targetReceiver = null;
12167
12168         final int NR = receivers.size();
12169         for (int i = 0; i < NR; i++) {
12170             final ResolveInfo info = receivers.get(i);
12171             if (info.activityInfo == null) {
12172                 continue;
12173             }
12174
12175             if (packageName.equals(info.activityInfo.packageName)) {
12176                 targetReceiver = info.activityInfo;
12177                 break;
12178             }
12179         }
12180
12181         if (targetReceiver == null) {
12182             return null;
12183         }
12184
12185         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
12186     }
12187
12188     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
12189             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
12190         if (pkgInfo.verifiers.length == 0) {
12191             return null;
12192         }
12193
12194         final int N = pkgInfo.verifiers.length;
12195         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
12196         for (int i = 0; i < N; i++) {
12197             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
12198
12199             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
12200                     receivers);
12201             if (comp == null) {
12202                 continue;
12203             }
12204
12205             final int verifierUid = getUidForVerifier(verifierInfo);
12206             if (verifierUid == -1) {
12207                 continue;
12208             }
12209
12210             if (DEBUG_VERIFY) {
12211                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
12212                         + " with the correct signature");
12213             }
12214             sufficientVerifiers.add(comp);
12215             verificationState.addSufficientVerifier(verifierUid);
12216         }
12217
12218         return sufficientVerifiers;
12219     }
12220
12221     private int getUidForVerifier(VerifierInfo verifierInfo) {
12222         synchronized (mPackages) {
12223             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
12224             if (pkg == null) {
12225                 return -1;
12226             } else if (pkg.mSignatures.length != 1) {
12227                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
12228                         + " has more than one signature; ignoring");
12229                 return -1;
12230             }
12231
12232             /*
12233              * If the public key of the package's signature does not match
12234              * our expected public key, then this is a different package and
12235              * we should skip.
12236              */
12237
12238             final byte[] expectedPublicKey;
12239             try {
12240                 final Signature verifierSig = pkg.mSignatures[0];
12241                 final PublicKey publicKey = verifierSig.getPublicKey();
12242                 expectedPublicKey = publicKey.getEncoded();
12243             } catch (CertificateException e) {
12244                 return -1;
12245             }
12246
12247             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
12248
12249             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
12250                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
12251                         + " does not have the expected public key; ignoring");
12252                 return -1;
12253             }
12254
12255             return pkg.applicationInfo.uid;
12256         }
12257     }
12258
12259     @Override
12260     public void finishPackageInstall(int token, boolean didLaunch) {
12261         enforceSystemOrRoot("Only the system is allowed to finish installs");
12262
12263         if (DEBUG_INSTALL) {
12264             Slog.v(TAG, "BM finishing package install for " + token);
12265         }
12266         Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
12267
12268         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
12269         mHandler.sendMessage(msg);
12270     }
12271
12272     /**
12273      * Get the verification agent timeout.
12274      *
12275      * @return verification timeout in milliseconds
12276      */
12277     private long getVerificationTimeout() {
12278         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
12279                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
12280                 DEFAULT_VERIFICATION_TIMEOUT);
12281     }
12282
12283     /**
12284      * Get the default verification agent response code.
12285      *
12286      * @return default verification response code
12287      */
12288     private int getDefaultVerificationResponse() {
12289         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12290                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
12291                 DEFAULT_VERIFICATION_RESPONSE);
12292     }
12293
12294     /**
12295      * Check whether or not package verification has been enabled.
12296      *
12297      * @return true if verification should be performed
12298      */
12299     private boolean isVerificationEnabled(int userId, int installFlags) {
12300         if (!DEFAULT_VERIFY_ENABLE) {
12301             return false;
12302         }
12303         // Ephemeral apps don't get the full verification treatment
12304         if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
12305             if (DEBUG_EPHEMERAL) {
12306                 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
12307             }
12308             return false;
12309         }
12310
12311         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
12312
12313         // Check if installing from ADB
12314         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
12315             // Do not run verification in a test harness environment
12316             if (ActivityManager.isRunningInTestHarness()) {
12317                 return false;
12318             }
12319             if (ensureVerifyAppsEnabled) {
12320                 return true;
12321             }
12322             // Check if the developer does not want package verification for ADB installs
12323             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12324                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
12325                 return false;
12326             }
12327         }
12328
12329         if (ensureVerifyAppsEnabled) {
12330             return true;
12331         }
12332
12333         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12334                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
12335     }
12336
12337     @Override
12338     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
12339             throws RemoteException {
12340         mContext.enforceCallingOrSelfPermission(
12341                 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
12342                 "Only intentfilter verification agents can verify applications");
12343
12344         final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
12345         final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
12346                 Binder.getCallingUid(), verificationCode, failedDomains);
12347         msg.arg1 = id;
12348         msg.obj = response;
12349         mHandler.sendMessage(msg);
12350     }
12351
12352     @Override
12353     public int getIntentVerificationStatus(String packageName, int userId) {
12354         synchronized (mPackages) {
12355             return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
12356         }
12357     }
12358
12359     @Override
12360     public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
12361         mContext.enforceCallingOrSelfPermission(
12362                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12363
12364         boolean result = false;
12365         synchronized (mPackages) {
12366             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
12367         }
12368         if (result) {
12369             scheduleWritePackageRestrictionsLocked(userId);
12370         }
12371         return result;
12372     }
12373
12374     @Override
12375     public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
12376             String packageName) {
12377         synchronized (mPackages) {
12378             return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
12379         }
12380     }
12381
12382     @Override
12383     public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
12384         if (TextUtils.isEmpty(packageName)) {
12385             return ParceledListSlice.emptyList();
12386         }
12387         synchronized (mPackages) {
12388             PackageParser.Package pkg = mPackages.get(packageName);
12389             if (pkg == null || pkg.activities == null) {
12390                 return ParceledListSlice.emptyList();
12391             }
12392             final int count = pkg.activities.size();
12393             ArrayList<IntentFilter> result = new ArrayList<>();
12394             for (int n=0; n<count; n++) {
12395                 PackageParser.Activity activity = pkg.activities.get(n);
12396                 if (activity.intents != null && activity.intents.size() > 0) {
12397                     result.addAll(activity.intents);
12398                 }
12399             }
12400             return new ParceledListSlice<>(result);
12401         }
12402     }
12403
12404     @Override
12405     public boolean setDefaultBrowserPackageName(String packageName, int userId) {
12406         mContext.enforceCallingOrSelfPermission(
12407                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12408
12409         synchronized (mPackages) {
12410             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
12411             if (packageName != null) {
12412                 result |= updateIntentVerificationStatus(packageName,
12413                         PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
12414                         userId);
12415                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
12416                         packageName, userId);
12417             }
12418             return result;
12419         }
12420     }
12421
12422     @Override
12423     public String getDefaultBrowserPackageName(int userId) {
12424         synchronized (mPackages) {
12425             return mSettings.getDefaultBrowserPackageNameLPw(userId);
12426         }
12427     }
12428
12429     /**
12430      * Get the "allow unknown sources" setting.
12431      *
12432      * @return the current "allow unknown sources" setting
12433      */
12434     private int getUnknownSourcesSettings() {
12435         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
12436                 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
12437                 -1);
12438     }
12439
12440     @Override
12441     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
12442         final int uid = Binder.getCallingUid();
12443         // writer
12444         synchronized (mPackages) {
12445             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
12446             if (targetPackageSetting == null) {
12447                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
12448             }
12449
12450             PackageSetting installerPackageSetting;
12451             if (installerPackageName != null) {
12452                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
12453                 if (installerPackageSetting == null) {
12454                     throw new IllegalArgumentException("Unknown installer package: "
12455                             + installerPackageName);
12456                 }
12457             } else {
12458                 installerPackageSetting = null;
12459             }
12460
12461             Signature[] callerSignature;
12462             Object obj = mSettings.getUserIdLPr(uid);
12463             if (obj != null) {
12464                 if (obj instanceof SharedUserSetting) {
12465                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
12466                 } else if (obj instanceof PackageSetting) {
12467                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
12468                 } else {
12469                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
12470                 }
12471             } else {
12472                 throw new SecurityException("Unknown calling UID: " + uid);
12473             }
12474
12475             // Verify: can't set installerPackageName to a package that is
12476             // not signed with the same cert as the caller.
12477             if (installerPackageSetting != null) {
12478                 if (compareSignatures(callerSignature,
12479                         installerPackageSetting.signatures.mSignatures)
12480                         != PackageManager.SIGNATURE_MATCH) {
12481                     throw new SecurityException(
12482                             "Caller does not have same cert as new installer package "
12483                             + installerPackageName);
12484                 }
12485             }
12486
12487             // Verify: if target already has an installer package, it must
12488             // be signed with the same cert as the caller.
12489             if (targetPackageSetting.installerPackageName != null) {
12490                 PackageSetting setting = mSettings.mPackages.get(
12491                         targetPackageSetting.installerPackageName);
12492                 // If the currently set package isn't valid, then it's always
12493                 // okay to change it.
12494                 if (setting != null) {
12495                     if (compareSignatures(callerSignature,
12496                             setting.signatures.mSignatures)
12497                             != PackageManager.SIGNATURE_MATCH) {
12498                         throw new SecurityException(
12499                                 "Caller does not have same cert as old installer package "
12500                                 + targetPackageSetting.installerPackageName);
12501                     }
12502                 }
12503             }
12504
12505             // Okay!
12506             targetPackageSetting.installerPackageName = installerPackageName;
12507             if (installerPackageName != null) {
12508                 mSettings.mInstallerPackages.add(installerPackageName);
12509             }
12510             scheduleWriteSettingsLocked();
12511         }
12512     }
12513
12514     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
12515         // Queue up an async operation since the package installation may take a little while.
12516         mHandler.post(new Runnable() {
12517             public void run() {
12518                 mHandler.removeCallbacks(this);
12519                  // Result object to be returned
12520                 PackageInstalledInfo res = new PackageInstalledInfo();
12521                 res.setReturnCode(currentStatus);
12522                 res.uid = -1;
12523                 res.pkg = null;
12524                 res.removedInfo = null;
12525                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12526                     args.doPreInstall(res.returnCode);
12527                     synchronized (mInstallLock) {
12528                         installPackageTracedLI(args, res);
12529                     }
12530                     args.doPostInstall(res.returnCode, res.uid);
12531                 }
12532
12533                 // A restore should be performed at this point if (a) the install
12534                 // succeeded, (b) the operation is not an update, and (c) the new
12535                 // package has not opted out of backup participation.
12536                 final boolean update = res.removedInfo != null
12537                         && res.removedInfo.removedPackage != null;
12538                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
12539                 boolean doRestore = !update
12540                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
12541
12542                 // Set up the post-install work request bookkeeping.  This will be used
12543                 // and cleaned up by the post-install event handling regardless of whether
12544                 // there's a restore pass performed.  Token values are >= 1.
12545                 int token;
12546                 if (mNextInstallToken < 0) mNextInstallToken = 1;
12547                 token = mNextInstallToken++;
12548
12549                 PostInstallData data = new PostInstallData(args, res);
12550                 mRunningInstalls.put(token, data);
12551                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
12552
12553                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
12554                     // Pass responsibility to the Backup Manager.  It will perform a
12555                     // restore if appropriate, then pass responsibility back to the
12556                     // Package Manager to run the post-install observer callbacks
12557                     // and broadcasts.
12558                     IBackupManager bm = IBackupManager.Stub.asInterface(
12559                             ServiceManager.getService(Context.BACKUP_SERVICE));
12560                     if (bm != null) {
12561                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
12562                                 + " to BM for possible restore");
12563                         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
12564                         try {
12565                             // TODO: http://b/22388012
12566                             if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
12567                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
12568                             } else {
12569                                 doRestore = false;
12570                             }
12571                         } catch (RemoteException e) {
12572                             // can't happen; the backup manager is local
12573                         } catch (Exception e) {
12574                             Slog.e(TAG, "Exception trying to enqueue restore", e);
12575                             doRestore = false;
12576                         }
12577                     } else {
12578                         Slog.e(TAG, "Backup Manager not found!");
12579                         doRestore = false;
12580                     }
12581                 }
12582
12583                 if (!doRestore) {
12584                     // No restore possible, or the Backup Manager was mysteriously not
12585                     // available -- just fire the post-install work request directly.
12586                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
12587
12588                     Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
12589
12590                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
12591                     mHandler.sendMessage(msg);
12592                 }
12593             }
12594         });
12595     }
12596
12597     /**
12598      * Callback from PackageSettings whenever an app is first transitioned out of the
12599      * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
12600      * the app was "launched" for a restoreAtInstall operation.  Therefore we check
12601      * here whether the app is the target of an ongoing install, and only send the
12602      * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
12603      * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
12604      * handling.
12605      */
12606     void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
12607         // Serialize this with the rest of the install-process message chain.  In the
12608         // restore-at-install case, this Runnable will necessarily run before the
12609         // POST_INSTALL message is processed, so the contents of mRunningInstalls
12610         // are coherent.  In the non-restore case, the app has already completed install
12611         // and been launched through some other means, so it is not in a problematic
12612         // state for observers to see the FIRST_LAUNCH signal.
12613         mHandler.post(new Runnable() {
12614             @Override
12615             public void run() {
12616                 for (int i = 0; i < mRunningInstalls.size(); i++) {
12617                     final PostInstallData data = mRunningInstalls.valueAt(i);
12618                     if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12619                         continue;
12620                     }
12621                     if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
12622                         // right package; but is it for the right user?
12623                         for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
12624                             if (userId == data.res.newUsers[uIndex]) {
12625                                 if (DEBUG_BACKUP) {
12626                                     Slog.i(TAG, "Package " + pkgName
12627                                             + " being restored so deferring FIRST_LAUNCH");
12628                                 }
12629                                 return;
12630                             }
12631                         }
12632                     }
12633                 }
12634                 // didn't find it, so not being restored
12635                 if (DEBUG_BACKUP) {
12636                     Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
12637                 }
12638                 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
12639             }
12640         });
12641     }
12642
12643     private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
12644         sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
12645                 installerPkg, null, userIds);
12646     }
12647
12648     private abstract class HandlerParams {
12649         private static final int MAX_RETRIES = 4;
12650
12651         /**
12652          * Number of times startCopy() has been attempted and had a non-fatal
12653          * error.
12654          */
12655         private int mRetries = 0;
12656
12657         /** User handle for the user requesting the information or installation. */
12658         private final UserHandle mUser;
12659         String traceMethod;
12660         int traceCookie;
12661
12662         HandlerParams(UserHandle user) {
12663             mUser = user;
12664         }
12665
12666         UserHandle getUser() {
12667             return mUser;
12668         }
12669
12670         HandlerParams setTraceMethod(String traceMethod) {
12671             this.traceMethod = traceMethod;
12672             return this;
12673         }
12674
12675         HandlerParams setTraceCookie(int traceCookie) {
12676             this.traceCookie = traceCookie;
12677             return this;
12678         }
12679
12680         final boolean startCopy() {
12681             boolean res;
12682             try {
12683                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
12684
12685                 if (++mRetries > MAX_RETRIES) {
12686                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
12687                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
12688                     handleServiceError();
12689                     return false;
12690                 } else {
12691                     handleStartCopy();
12692                     res = true;
12693                 }
12694             } catch (RemoteException e) {
12695                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
12696                 mHandler.sendEmptyMessage(MCS_RECONNECT);
12697                 res = false;
12698             }
12699             handleReturnCode();
12700             return res;
12701         }
12702
12703         final void serviceError() {
12704             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
12705             handleServiceError();
12706             handleReturnCode();
12707         }
12708
12709         abstract void handleStartCopy() throws RemoteException;
12710         abstract void handleServiceError();
12711         abstract void handleReturnCode();
12712     }
12713
12714     class MeasureParams extends HandlerParams {
12715         private final PackageStats mStats;
12716         private boolean mSuccess;
12717
12718         private final IPackageStatsObserver mObserver;
12719
12720         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
12721             super(new UserHandle(stats.userHandle));
12722             mObserver = observer;
12723             mStats = stats;
12724         }
12725
12726         @Override
12727         public String toString() {
12728             return "MeasureParams{"
12729                 + Integer.toHexString(System.identityHashCode(this))
12730                 + " " + mStats.packageName + "}";
12731         }
12732
12733         @Override
12734         void handleStartCopy() throws RemoteException {
12735             synchronized (mInstallLock) {
12736                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
12737             }
12738
12739             if (mSuccess) {
12740                 boolean mounted = false;
12741                 try {
12742                     final String status = Environment.getExternalStorageState();
12743                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
12744                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
12745                 } catch (Exception e) {
12746                 }
12747
12748                 if (mounted) {
12749                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
12750
12751                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
12752                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
12753
12754                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
12755                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
12756
12757                     // Always subtract cache size, since it's a subdirectory
12758                     mStats.externalDataSize -= mStats.externalCacheSize;
12759
12760                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
12761                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
12762
12763                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
12764                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
12765                 }
12766             }
12767         }
12768
12769         @Override
12770         void handleReturnCode() {
12771             if (mObserver != null) {
12772                 try {
12773                     mObserver.onGetStatsCompleted(mStats, mSuccess);
12774                 } catch (RemoteException e) {
12775                     Slog.i(TAG, "Observer no longer exists.");
12776                 }
12777             }
12778         }
12779
12780         @Override
12781         void handleServiceError() {
12782             Slog.e(TAG, "Could not measure application " + mStats.packageName
12783                             + " external storage");
12784         }
12785     }
12786
12787     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
12788             throws RemoteException {
12789         long result = 0;
12790         for (File path : paths) {
12791             result += mcs.calculateDirectorySize(path.getAbsolutePath());
12792         }
12793         return result;
12794     }
12795
12796     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
12797         for (File path : paths) {
12798             try {
12799                 mcs.clearDirectory(path.getAbsolutePath());
12800             } catch (RemoteException e) {
12801             }
12802         }
12803     }
12804
12805     static class OriginInfo {
12806         /**
12807          * Location where install is coming from, before it has been
12808          * copied/renamed into place. This could be a single monolithic APK
12809          * file, or a cluster directory. This location may be untrusted.
12810          */
12811         final File file;
12812         final String cid;
12813
12814         /**
12815          * Flag indicating that {@link #file} or {@link #cid} has already been
12816          * staged, meaning downstream users don't need to defensively copy the
12817          * contents.
12818          */
12819         final boolean staged;
12820
12821         /**
12822          * Flag indicating that {@link #file} or {@link #cid} is an already
12823          * installed app that is being moved.
12824          */
12825         final boolean existing;
12826
12827         final String resolvedPath;
12828         final File resolvedFile;
12829
12830         static OriginInfo fromNothing() {
12831             return new OriginInfo(null, null, false, false);
12832         }
12833
12834         static OriginInfo fromUntrustedFile(File file) {
12835             return new OriginInfo(file, null, false, false);
12836         }
12837
12838         static OriginInfo fromExistingFile(File file) {
12839             return new OriginInfo(file, null, false, true);
12840         }
12841
12842         static OriginInfo fromStagedFile(File file) {
12843             return new OriginInfo(file, null, true, false);
12844         }
12845
12846         static OriginInfo fromStagedContainer(String cid) {
12847             return new OriginInfo(null, cid, true, false);
12848         }
12849
12850         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
12851             this.file = file;
12852             this.cid = cid;
12853             this.staged = staged;
12854             this.existing = existing;
12855
12856             if (cid != null) {
12857                 resolvedPath = PackageHelper.getSdDir(cid);
12858                 resolvedFile = new File(resolvedPath);
12859             } else if (file != null) {
12860                 resolvedPath = file.getAbsolutePath();
12861                 resolvedFile = file;
12862             } else {
12863                 resolvedPath = null;
12864                 resolvedFile = null;
12865             }
12866         }
12867     }
12868
12869     static class MoveInfo {
12870         final int moveId;
12871         final String fromUuid;
12872         final String toUuid;
12873         final String packageName;
12874         final String dataAppName;
12875         final int appId;
12876         final String seinfo;
12877         final int targetSdkVersion;
12878
12879         public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
12880                 String dataAppName, int appId, String seinfo, int targetSdkVersion) {
12881             this.moveId = moveId;
12882             this.fromUuid = fromUuid;
12883             this.toUuid = toUuid;
12884             this.packageName = packageName;
12885             this.dataAppName = dataAppName;
12886             this.appId = appId;
12887             this.seinfo = seinfo;
12888             this.targetSdkVersion = targetSdkVersion;
12889         }
12890     }
12891
12892     static class VerificationInfo {
12893         /** A constant used to indicate that a uid value is not present. */
12894         public static final int NO_UID = -1;
12895
12896         /** URI referencing where the package was downloaded from. */
12897         final Uri originatingUri;
12898
12899         /** HTTP referrer URI associated with the originatingURI. */
12900         final Uri referrer;
12901
12902         /** UID of the application that the install request originated from. */
12903         final int originatingUid;
12904
12905         /** UID of application requesting the install */
12906         final int installerUid;
12907
12908         VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
12909             this.originatingUri = originatingUri;
12910             this.referrer = referrer;
12911             this.originatingUid = originatingUid;
12912             this.installerUid = installerUid;
12913         }
12914     }
12915
12916     class InstallParams extends HandlerParams {
12917         final OriginInfo origin;
12918         final MoveInfo move;
12919         final IPackageInstallObserver2 observer;
12920         int installFlags;
12921         final String installerPackageName;
12922         final String volumeUuid;
12923         private InstallArgs mArgs;
12924         private int mRet;
12925         final String packageAbiOverride;
12926         final String[] grantedRuntimePermissions;
12927         final VerificationInfo verificationInfo;
12928         final Certificate[][] certificates;
12929
12930         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
12931                 int installFlags, String installerPackageName, String volumeUuid,
12932                 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
12933                 String[] grantedPermissions, Certificate[][] certificates) {
12934             super(user);
12935             this.origin = origin;
12936             this.move = move;
12937             this.observer = observer;
12938             this.installFlags = installFlags;
12939             this.installerPackageName = installerPackageName;
12940             this.volumeUuid = volumeUuid;
12941             this.verificationInfo = verificationInfo;
12942             this.packageAbiOverride = packageAbiOverride;
12943             this.grantedRuntimePermissions = grantedPermissions;
12944             this.certificates = certificates;
12945         }
12946
12947         @Override
12948         public String toString() {
12949             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
12950                     + " file=" + origin.file + " cid=" + origin.cid + "}";
12951         }
12952
12953         private int installLocationPolicy(PackageInfoLite pkgLite) {
12954             String packageName = pkgLite.packageName;
12955             int installLocation = pkgLite.installLocation;
12956             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
12957             // reader
12958             synchronized (mPackages) {
12959                 // Currently installed package which the new package is attempting to replace or
12960                 // null if no such package is installed.
12961                 PackageParser.Package installedPkg = mPackages.get(packageName);
12962                 // Package which currently owns the data which the new package will own if installed.
12963                 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
12964                 // will be null whereas dataOwnerPkg will contain information about the package
12965                 // which was uninstalled while keeping its data.
12966                 PackageParser.Package dataOwnerPkg = installedPkg;
12967                 if (dataOwnerPkg  == null) {
12968                     PackageSetting ps = mSettings.mPackages.get(packageName);
12969                     if (ps != null) {
12970                         dataOwnerPkg = ps.pkg;
12971                     }
12972                 }
12973
12974                 if (dataOwnerPkg != null) {
12975                     // If installed, the package will get access to data left on the device by its
12976                     // predecessor. As a security measure, this is permited only if this is not a
12977                     // version downgrade or if the predecessor package is marked as debuggable and
12978                     // a downgrade is explicitly requested.
12979                     //
12980                     // On debuggable platform builds, downgrades are permitted even for
12981                     // non-debuggable packages to make testing easier. Debuggable platform builds do
12982                     // not offer security guarantees and thus it's OK to disable some security
12983                     // mechanisms to make debugging/testing easier on those builds. However, even on
12984                     // debuggable builds downgrades of packages are permitted only if requested via
12985                     // installFlags. This is because we aim to keep the behavior of debuggable
12986                     // platform builds as close as possible to the behavior of non-debuggable
12987                     // platform builds.
12988                     final boolean downgradeRequested =
12989                             (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
12990                     final boolean packageDebuggable =
12991                                 (dataOwnerPkg.applicationInfo.flags
12992                                         & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
12993                     final boolean downgradePermitted =
12994                             (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
12995                     if (!downgradePermitted) {
12996                         try {
12997                             checkDowngrade(dataOwnerPkg, pkgLite);
12998                         } catch (PackageManagerException e) {
12999                             Slog.w(TAG, "Downgrade detected: " + e.getMessage());
13000                             return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
13001                         }
13002                     }
13003                 }
13004
13005                 if (installedPkg != null) {
13006                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
13007                         // Check for updated system application.
13008                         if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13009                             if (onSd) {
13010                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
13011                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
13012                             }
13013                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
13014                         } else {
13015                             if (onSd) {
13016                                 // Install flag overrides everything.
13017                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
13018                             }
13019                             // If current upgrade specifies particular preference
13020                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
13021                                 // Application explicitly specified internal.
13022                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
13023                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
13024                                 // App explictly prefers external. Let policy decide
13025                             } else {
13026                                 // Prefer previous location
13027                                 if (isExternal(installedPkg)) {
13028                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
13029                                 }
13030                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
13031                             }
13032                         }
13033                     } else {
13034                         // Invalid install. Return error code
13035                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
13036                     }
13037                 }
13038             }
13039             // All the special cases have been taken care of.
13040             // Return result based on recommended install location.
13041             if (onSd) {
13042                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
13043             }
13044             return pkgLite.recommendedInstallLocation;
13045         }
13046
13047         /*
13048          * Invoke remote method to get package information and install
13049          * location values. Override install location based on default
13050          * policy if needed and then create install arguments based
13051          * on the install location.
13052          */
13053         public void handleStartCopy() throws RemoteException {
13054             int ret = PackageManager.INSTALL_SUCCEEDED;
13055
13056             // If we're already staged, we've firmly committed to an install location
13057             if (origin.staged) {
13058                 if (origin.file != null) {
13059                     installFlags |= PackageManager.INSTALL_INTERNAL;
13060                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
13061                 } else if (origin.cid != null) {
13062                     installFlags |= PackageManager.INSTALL_EXTERNAL;
13063                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
13064                 } else {
13065                     throw new IllegalStateException("Invalid stage location");
13066                 }
13067             }
13068
13069             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
13070             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
13071             final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13072             PackageInfoLite pkgLite = null;
13073
13074             if (onInt && onSd) {
13075                 // Check if both bits are set.
13076                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
13077                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
13078             } else if (onSd && ephemeral) {
13079                 Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
13080                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
13081             } else {
13082                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
13083                         packageAbiOverride);
13084
13085                 if (DEBUG_EPHEMERAL && ephemeral) {
13086                     Slog.v(TAG, "pkgLite for install: " + pkgLite);
13087                 }
13088
13089                 /*
13090                  * If we have too little free space, try to free cache
13091                  * before giving up.
13092                  */
13093                 if (!origin.staged && pkgLite.recommendedInstallLocation
13094                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
13095                     // TODO: focus freeing disk space on the target device
13096                     final StorageManager storage = StorageManager.from(mContext);
13097                     final long lowThreshold = storage.getStorageLowBytes(
13098                             Environment.getDataDirectory());
13099
13100                     final long sizeBytes = mContainerService.calculateInstalledSize(
13101                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
13102
13103                     try {
13104                         mInstaller.freeCache(null, sizeBytes + lowThreshold);
13105                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
13106                                 installFlags, packageAbiOverride);
13107                     } catch (InstallerException e) {
13108                         Slog.w(TAG, "Failed to free cache", e);
13109                     }
13110
13111                     /*
13112                      * The cache free must have deleted the file we
13113                      * downloaded to install.
13114                      *
13115                      * TODO: fix the "freeCache" call to not delete
13116                      *       the file we care about.
13117                      */
13118                     if (pkgLite.recommendedInstallLocation
13119                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
13120                         pkgLite.recommendedInstallLocation
13121                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
13122                     }
13123                 }
13124             }
13125
13126             if (ret == PackageManager.INSTALL_SUCCEEDED) {
13127                 int loc = pkgLite.recommendedInstallLocation;
13128                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
13129                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
13130                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
13131                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
13132                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
13133                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
13134                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
13135                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
13136                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
13137                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
13138                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
13139                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
13140                 } else {
13141                     // Override with defaults if needed.
13142                     loc = installLocationPolicy(pkgLite);
13143                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
13144                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
13145                     } else if (!onSd && !onInt) {
13146                         // Override install location with flags
13147                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
13148                             // Set the flag to install on external media.
13149                             installFlags |= PackageManager.INSTALL_EXTERNAL;
13150                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
13151                         } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
13152                             if (DEBUG_EPHEMERAL) {
13153                                 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
13154                             }
13155                             installFlags |= PackageManager.INSTALL_EPHEMERAL;
13156                             installFlags &= ~(PackageManager.INSTALL_EXTERNAL
13157                                     |PackageManager.INSTALL_INTERNAL);
13158                         } else {
13159                             // Make sure the flag for installing on external
13160                             // media is unset
13161                             installFlags |= PackageManager.INSTALL_INTERNAL;
13162                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
13163                         }
13164                     }
13165                 }
13166             }
13167
13168             final InstallArgs args = createInstallArgs(this);
13169             mArgs = args;
13170
13171             if (ret == PackageManager.INSTALL_SUCCEEDED) {
13172                 // TODO: http://b/22976637
13173                 // Apps installed for "all" users use the device owner to verify the app
13174                 UserHandle verifierUser = getUser();
13175                 if (verifierUser == UserHandle.ALL) {
13176                     verifierUser = UserHandle.SYSTEM;
13177                 }
13178
13179                 /*
13180                  * Determine if we have any installed package verifiers. If we
13181                  * do, then we'll defer to them to verify the packages.
13182                  */
13183                 final int requiredUid = mRequiredVerifierPackage == null ? -1
13184                         : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
13185                                 verifierUser.getIdentifier());
13186                 if (!origin.existing && requiredUid != -1
13187                         && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
13188                     final Intent verification = new Intent(
13189                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
13190                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13191                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
13192                             PACKAGE_MIME_TYPE);
13193                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13194
13195                     // Query all live verifiers based on current user state
13196                     final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
13197                             PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
13198
13199                     if (DEBUG_VERIFY) {
13200                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
13201                                 + verification.toString() + " with " + pkgLite.verifiers.length
13202                                 + " optional verifiers");
13203                     }
13204
13205                     final int verificationId = mPendingVerificationToken++;
13206
13207                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13208
13209                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
13210                             installerPackageName);
13211
13212                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
13213                             installFlags);
13214
13215                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
13216                             pkgLite.packageName);
13217
13218                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
13219                             pkgLite.versionCode);
13220
13221                     if (verificationInfo != null) {
13222                         if (verificationInfo.originatingUri != null) {
13223                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
13224                                     verificationInfo.originatingUri);
13225                         }
13226                         if (verificationInfo.referrer != null) {
13227                             verification.putExtra(Intent.EXTRA_REFERRER,
13228                                     verificationInfo.referrer);
13229                         }
13230                         if (verificationInfo.originatingUid >= 0) {
13231                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
13232                                     verificationInfo.originatingUid);
13233                         }
13234                         if (verificationInfo.installerUid >= 0) {
13235                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
13236                                     verificationInfo.installerUid);
13237                         }
13238                     }
13239
13240                     final PackageVerificationState verificationState = new PackageVerificationState(
13241                             requiredUid, args);
13242
13243                     mPendingVerification.append(verificationId, verificationState);
13244
13245                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
13246                             receivers, verificationState);
13247
13248                     /*
13249                      * If any sufficient verifiers were listed in the package
13250                      * manifest, attempt to ask them.
13251                      */
13252                     if (sufficientVerifiers != null) {
13253                         final int N = sufficientVerifiers.size();
13254                         if (N == 0) {
13255                             Slog.i(TAG, "Additional verifiers required, but none installed.");
13256                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
13257                         } else {
13258                             for (int i = 0; i < N; i++) {
13259                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
13260
13261                                 final Intent sufficientIntent = new Intent(verification);
13262                                 sufficientIntent.setComponent(verifierComponent);
13263                                 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
13264                             }
13265                         }
13266                     }
13267
13268                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
13269                             mRequiredVerifierPackage, receivers);
13270                     if (ret == PackageManager.INSTALL_SUCCEEDED
13271                             && mRequiredVerifierPackage != null) {
13272                         Trace.asyncTraceBegin(
13273                                 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
13274                         /*
13275                          * Send the intent to the required verification agent,
13276                          * but only start the verification timeout after the
13277                          * target BroadcastReceivers have run.
13278                          */
13279                         verification.setComponent(requiredVerifierComponent);
13280                         mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
13281                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13282                                 new BroadcastReceiver() {
13283                                     @Override
13284                                     public void onReceive(Context context, Intent intent) {
13285                                         final Message msg = mHandler
13286                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
13287                                         msg.arg1 = verificationId;
13288                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
13289                                     }
13290                                 }, null, 0, null, null);
13291
13292                         /*
13293                          * We don't want the copy to proceed until verification
13294                          * succeeds, so null out this field.
13295                          */
13296                         mArgs = null;
13297                     }
13298                 } else {
13299                     /*
13300                      * No package verification is enabled, so immediately start
13301                      * the remote call to initiate copy using temporary file.
13302                      */
13303                     ret = args.copyApk(mContainerService, true);
13304                 }
13305             }
13306
13307             mRet = ret;
13308         }
13309
13310         @Override
13311         void handleReturnCode() {
13312             // If mArgs is null, then MCS couldn't be reached. When it
13313             // reconnects, it will try again to install. At that point, this
13314             // will succeed.
13315             if (mArgs != null) {
13316                 processPendingInstall(mArgs, mRet);
13317             }
13318         }
13319
13320         @Override
13321         void handleServiceError() {
13322             mArgs = createInstallArgs(this);
13323             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13324         }
13325
13326         public boolean isForwardLocked() {
13327             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13328         }
13329     }
13330
13331     /**
13332      * Used during creation of InstallArgs
13333      *
13334      * @param installFlags package installation flags
13335      * @return true if should be installed on external storage
13336      */
13337     private static boolean installOnExternalAsec(int installFlags) {
13338         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
13339             return false;
13340         }
13341         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13342             return true;
13343         }
13344         return false;
13345     }
13346
13347     /**
13348      * Used during creation of InstallArgs
13349      *
13350      * @param installFlags package installation flags
13351      * @return true if should be installed as forward locked
13352      */
13353     private static boolean installForwardLocked(int installFlags) {
13354         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13355     }
13356
13357     private InstallArgs createInstallArgs(InstallParams params) {
13358         if (params.move != null) {
13359             return new MoveInstallArgs(params);
13360         } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
13361             return new AsecInstallArgs(params);
13362         } else {
13363             return new FileInstallArgs(params);
13364         }
13365     }
13366
13367     /**
13368      * Create args that describe an existing installed package. Typically used
13369      * when cleaning up old installs, or used as a move source.
13370      */
13371     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
13372             String resourcePath, String[] instructionSets) {
13373         final boolean isInAsec;
13374         if (installOnExternalAsec(installFlags)) {
13375             /* Apps on SD card are always in ASEC containers. */
13376             isInAsec = true;
13377         } else if (installForwardLocked(installFlags)
13378                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
13379             /*
13380              * Forward-locked apps are only in ASEC containers if they're the
13381              * new style
13382              */
13383             isInAsec = true;
13384         } else {
13385             isInAsec = false;
13386         }
13387
13388         if (isInAsec) {
13389             return new AsecInstallArgs(codePath, instructionSets,
13390                     installOnExternalAsec(installFlags), installForwardLocked(installFlags));
13391         } else {
13392             return new FileInstallArgs(codePath, resourcePath, instructionSets);
13393         }
13394     }
13395
13396     static abstract class InstallArgs {
13397         /** @see InstallParams#origin */
13398         final OriginInfo origin;
13399         /** @see InstallParams#move */
13400         final MoveInfo move;
13401
13402         final IPackageInstallObserver2 observer;
13403         // Always refers to PackageManager flags only
13404         final int installFlags;
13405         final String installerPackageName;
13406         final String volumeUuid;
13407         final UserHandle user;
13408         final String abiOverride;
13409         final String[] installGrantPermissions;
13410         /** If non-null, drop an async trace when the install completes */
13411         final String traceMethod;
13412         final int traceCookie;
13413         final Certificate[][] certificates;
13414
13415         // The list of instruction sets supported by this app. This is currently
13416         // only used during the rmdex() phase to clean up resources. We can get rid of this
13417         // if we move dex files under the common app path.
13418         /* nullable */ String[] instructionSets;
13419
13420         InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
13421                 int installFlags, String installerPackageName, String volumeUuid,
13422                 UserHandle user, String[] instructionSets,
13423                 String abiOverride, String[] installGrantPermissions,
13424                 String traceMethod, int traceCookie, Certificate[][] certificates) {
13425             this.origin = origin;
13426             this.move = move;
13427             this.installFlags = installFlags;
13428             this.observer = observer;
13429             this.installerPackageName = installerPackageName;
13430             this.volumeUuid = volumeUuid;
13431             this.user = user;
13432             this.instructionSets = instructionSets;
13433             this.abiOverride = abiOverride;
13434             this.installGrantPermissions = installGrantPermissions;
13435             this.traceMethod = traceMethod;
13436             this.traceCookie = traceCookie;
13437             this.certificates = certificates;
13438         }
13439
13440         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
13441         abstract int doPreInstall(int status);
13442
13443         /**
13444          * Rename package into final resting place. All paths on the given
13445          * scanned package should be updated to reflect the rename.
13446          */
13447         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
13448         abstract int doPostInstall(int status, int uid);
13449
13450         /** @see PackageSettingBase#codePathString */
13451         abstract String getCodePath();
13452         /** @see PackageSettingBase#resourcePathString */
13453         abstract String getResourcePath();
13454
13455         // Need installer lock especially for dex file removal.
13456         abstract void cleanUpResourcesLI();
13457         abstract boolean doPostDeleteLI(boolean delete);
13458
13459         /**
13460          * Called before the source arguments are copied. This is used mostly
13461          * for MoveParams when it needs to read the source file to put it in the
13462          * destination.
13463          */
13464         int doPreCopy() {
13465             return PackageManager.INSTALL_SUCCEEDED;
13466         }
13467
13468         /**
13469          * Called after the source arguments are copied. This is used mostly for
13470          * MoveParams when it needs to read the source file to put it in the
13471          * destination.
13472          */
13473         int doPostCopy(int uid) {
13474             return PackageManager.INSTALL_SUCCEEDED;
13475         }
13476
13477         protected boolean isFwdLocked() {
13478             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13479         }
13480
13481         protected boolean isExternalAsec() {
13482             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
13483         }
13484
13485         protected boolean isEphemeral() {
13486             return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13487         }
13488
13489         UserHandle getUser() {
13490             return user;
13491         }
13492     }
13493
13494     private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
13495         if (!allCodePaths.isEmpty()) {
13496             if (instructionSets == null) {
13497                 throw new IllegalStateException("instructionSet == null");
13498             }
13499             String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
13500             for (String codePath : allCodePaths) {
13501                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
13502                     try {
13503                         mInstaller.rmdex(codePath, dexCodeInstructionSet);
13504                     } catch (InstallerException ignored) {
13505                     }
13506                 }
13507             }
13508         }
13509     }
13510
13511     /**
13512      * Logic to handle installation of non-ASEC applications, including copying
13513      * and renaming logic.
13514      */
13515     class FileInstallArgs extends InstallArgs {
13516         private File codeFile;
13517         private File resourceFile;
13518
13519         // Example topology:
13520         // /data/app/com.example/base.apk
13521         // /data/app/com.example/split_foo.apk
13522         // /data/app/com.example/lib/arm/libfoo.so
13523         // /data/app/com.example/lib/arm64/libfoo.so
13524         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
13525
13526         /** New install */
13527         FileInstallArgs(InstallParams params) {
13528             super(params.origin, params.move, params.observer, params.installFlags,
13529                     params.installerPackageName, params.volumeUuid,
13530                     params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
13531                     params.grantedRuntimePermissions,
13532                     params.traceMethod, params.traceCookie, params.certificates);
13533             if (isFwdLocked()) {
13534                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
13535             }
13536         }
13537
13538         /** Existing install */
13539         FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
13540             super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
13541                     null, null, null, 0, null /*certificates*/);
13542             this.codeFile = (codePath != null) ? new File(codePath) : null;
13543             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
13544         }
13545
13546         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13547             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
13548             try {
13549                 return doCopyApk(imcs, temp);
13550             } finally {
13551                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13552             }
13553         }
13554
13555         private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13556             if (origin.staged) {
13557                 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
13558                 codeFile = origin.file;
13559                 resourceFile = origin.file;
13560                 return PackageManager.INSTALL_SUCCEEDED;
13561             }
13562
13563             try {
13564                 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13565                 final File tempDir =
13566                         mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
13567                 codeFile = tempDir;
13568                 resourceFile = tempDir;
13569             } catch (IOException e) {
13570                 Slog.w(TAG, "Failed to create copy file: " + e);
13571                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
13572             }
13573
13574             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
13575                 @Override
13576                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
13577                     if (!FileUtils.isValidExtFilename(name)) {
13578                         throw new IllegalArgumentException("Invalid filename: " + name);
13579                     }
13580                     try {
13581                         final File file = new File(codeFile, name);
13582                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
13583                                 O_RDWR | O_CREAT, 0644);
13584                         Os.chmod(file.getAbsolutePath(), 0644);
13585                         return new ParcelFileDescriptor(fd);
13586                     } catch (ErrnoException e) {
13587                         throw new RemoteException("Failed to open: " + e.getMessage());
13588                     }
13589                 }
13590             };
13591
13592             int ret = PackageManager.INSTALL_SUCCEEDED;
13593             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
13594             if (ret != PackageManager.INSTALL_SUCCEEDED) {
13595                 Slog.e(TAG, "Failed to copy package");
13596                 return ret;
13597             }
13598
13599             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
13600             NativeLibraryHelper.Handle handle = null;
13601             try {
13602                 handle = NativeLibraryHelper.Handle.create(codeFile);
13603                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
13604                         abiOverride);
13605             } catch (IOException e) {
13606                 Slog.e(TAG, "Copying native libraries failed", e);
13607                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13608             } finally {
13609                 IoUtils.closeQuietly(handle);
13610             }
13611
13612             return ret;
13613         }
13614
13615         int doPreInstall(int status) {
13616             if (status != PackageManager.INSTALL_SUCCEEDED) {
13617                 cleanUp();
13618             }
13619             return status;
13620         }
13621
13622         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13623             if (status != PackageManager.INSTALL_SUCCEEDED) {
13624                 cleanUp();
13625                 return false;
13626             }
13627
13628             final File targetDir = codeFile.getParentFile();
13629             final File beforeCodeFile = codeFile;
13630             final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
13631
13632             if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
13633             try {
13634                 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
13635             } catch (ErrnoException e) {
13636                 Slog.w(TAG, "Failed to rename", e);
13637                 return false;
13638             }
13639
13640             if (!SELinux.restoreconRecursive(afterCodeFile)) {
13641                 Slog.w(TAG, "Failed to restorecon");
13642                 return false;
13643             }
13644
13645             // Reflect the rename internally
13646             codeFile = afterCodeFile;
13647             resourceFile = afterCodeFile;
13648
13649             // Reflect the rename in scanned details
13650             pkg.setCodePath(afterCodeFile.getAbsolutePath());
13651             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13652                     afterCodeFile, pkg.baseCodePath));
13653             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13654                     afterCodeFile, pkg.splitCodePaths));
13655
13656             // Reflect the rename in app info
13657             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13658             pkg.setApplicationInfoCodePath(pkg.codePath);
13659             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13660             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13661             pkg.setApplicationInfoResourcePath(pkg.codePath);
13662             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13663             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13664
13665             return true;
13666         }
13667
13668         int doPostInstall(int status, int uid) {
13669             if (status != PackageManager.INSTALL_SUCCEEDED) {
13670                 cleanUp();
13671             }
13672             return status;
13673         }
13674
13675         @Override
13676         String getCodePath() {
13677             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
13678         }
13679
13680         @Override
13681         String getResourcePath() {
13682             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
13683         }
13684
13685         private boolean cleanUp() {
13686             if (codeFile == null || !codeFile.exists()) {
13687                 return false;
13688             }
13689
13690             removeCodePathLI(codeFile);
13691
13692             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
13693                 resourceFile.delete();
13694             }
13695
13696             return true;
13697         }
13698
13699         void cleanUpResourcesLI() {
13700             // Try enumerating all code paths before deleting
13701             List<String> allCodePaths = Collections.EMPTY_LIST;
13702             if (codeFile != null && codeFile.exists()) {
13703                 try {
13704                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
13705                     allCodePaths = pkg.getAllCodePaths();
13706                 } catch (PackageParserException e) {
13707                     // Ignored; we tried our best
13708                 }
13709             }
13710
13711             cleanUp();
13712             removeDexFiles(allCodePaths, instructionSets);
13713         }
13714
13715         boolean doPostDeleteLI(boolean delete) {
13716             // XXX err, shouldn't we respect the delete flag?
13717             cleanUpResourcesLI();
13718             return true;
13719         }
13720     }
13721
13722     private boolean isAsecExternal(String cid) {
13723         final String asecPath = PackageHelper.getSdFilesystem(cid);
13724         return !asecPath.startsWith(mAsecInternalPath);
13725     }
13726
13727     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
13728             PackageManagerException {
13729         if (copyRet < 0) {
13730             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
13731                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
13732                 throw new PackageManagerException(copyRet, message);
13733             }
13734         }
13735     }
13736
13737     /**
13738      * Extract the MountService "container ID" from the full code path of an
13739      * .apk.
13740      */
13741     static String cidFromCodePath(String fullCodePath) {
13742         int eidx = fullCodePath.lastIndexOf("/");
13743         String subStr1 = fullCodePath.substring(0, eidx);
13744         int sidx = subStr1.lastIndexOf("/");
13745         return subStr1.substring(sidx+1, eidx);
13746     }
13747
13748     /**
13749      * Logic to handle installation of ASEC applications, including copying and
13750      * renaming logic.
13751      */
13752     class AsecInstallArgs extends InstallArgs {
13753         static final String RES_FILE_NAME = "pkg.apk";
13754         static final String PUBLIC_RES_FILE_NAME = "res.zip";
13755
13756         String cid;
13757         String packagePath;
13758         String resourcePath;
13759
13760         /** New install */
13761         AsecInstallArgs(InstallParams params) {
13762             super(params.origin, params.move, params.observer, params.installFlags,
13763                     params.installerPackageName, params.volumeUuid,
13764                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
13765                     params.grantedRuntimePermissions,
13766                     params.traceMethod, params.traceCookie, params.certificates);
13767         }
13768
13769         /** Existing install */
13770         AsecInstallArgs(String fullCodePath, String[] instructionSets,
13771                         boolean isExternal, boolean isForwardLocked) {
13772             super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
13773               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13774                     instructionSets, null, null, null, 0, null /*certificates*/);
13775             // Hackily pretend we're still looking at a full code path
13776             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
13777                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
13778             }
13779
13780             // Extract cid from fullCodePath
13781             int eidx = fullCodePath.lastIndexOf("/");
13782             String subStr1 = fullCodePath.substring(0, eidx);
13783             int sidx = subStr1.lastIndexOf("/");
13784             cid = subStr1.substring(sidx+1, eidx);
13785             setMountPath(subStr1);
13786         }
13787
13788         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
13789             super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
13790               | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13791                     instructionSets, null, null, null, 0, null /*certificates*/);
13792             this.cid = cid;
13793             setMountPath(PackageHelper.getSdDir(cid));
13794         }
13795
13796         void createCopyFile() {
13797             cid = mInstallerService.allocateExternalStageCidLegacy();
13798         }
13799
13800         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13801             if (origin.staged && origin.cid != null) {
13802                 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
13803                 cid = origin.cid;
13804                 setMountPath(PackageHelper.getSdDir(cid));
13805                 return PackageManager.INSTALL_SUCCEEDED;
13806             }
13807
13808             if (temp) {
13809                 createCopyFile();
13810             } else {
13811                 /*
13812                  * Pre-emptively destroy the container since it's destroyed if
13813                  * copying fails due to it existing anyway.
13814                  */
13815                 PackageHelper.destroySdDir(cid);
13816             }
13817
13818             final String newMountPath = imcs.copyPackageToContainer(
13819                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
13820                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
13821
13822             if (newMountPath != null) {
13823                 setMountPath(newMountPath);
13824                 return PackageManager.INSTALL_SUCCEEDED;
13825             } else {
13826                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13827             }
13828         }
13829
13830         @Override
13831         String getCodePath() {
13832             return packagePath;
13833         }
13834
13835         @Override
13836         String getResourcePath() {
13837             return resourcePath;
13838         }
13839
13840         int doPreInstall(int status) {
13841             if (status != PackageManager.INSTALL_SUCCEEDED) {
13842                 // Destroy container
13843                 PackageHelper.destroySdDir(cid);
13844             } else {
13845                 boolean mounted = PackageHelper.isContainerMounted(cid);
13846                 if (!mounted) {
13847                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
13848                             Process.SYSTEM_UID);
13849                     if (newMountPath != null) {
13850                         setMountPath(newMountPath);
13851                     } else {
13852                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13853                     }
13854                 }
13855             }
13856             return status;
13857         }
13858
13859         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13860             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
13861             String newMountPath = null;
13862             if (PackageHelper.isContainerMounted(cid)) {
13863                 // Unmount the container
13864                 if (!PackageHelper.unMountSdDir(cid)) {
13865                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
13866                     return false;
13867                 }
13868             }
13869             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13870                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
13871                         " which might be stale. Will try to clean up.");
13872                 // Clean up the stale container and proceed to recreate.
13873                 if (!PackageHelper.destroySdDir(newCacheId)) {
13874                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
13875                     return false;
13876                 }
13877                 // Successfully cleaned up stale container. Try to rename again.
13878                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13879                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
13880                             + " inspite of cleaning it up.");
13881                     return false;
13882                 }
13883             }
13884             if (!PackageHelper.isContainerMounted(newCacheId)) {
13885                 Slog.w(TAG, "Mounting container " + newCacheId);
13886                 newMountPath = PackageHelper.mountSdDir(newCacheId,
13887                         getEncryptKey(), Process.SYSTEM_UID);
13888             } else {
13889                 newMountPath = PackageHelper.getSdDir(newCacheId);
13890             }
13891             if (newMountPath == null) {
13892                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
13893                 return false;
13894             }
13895             Log.i(TAG, "Succesfully renamed " + cid +
13896                     " to " + newCacheId +
13897                     " at new path: " + newMountPath);
13898             cid = newCacheId;
13899
13900             final File beforeCodeFile = new File(packagePath);
13901             setMountPath(newMountPath);
13902             final File afterCodeFile = new File(packagePath);
13903
13904             // Reflect the rename in scanned details
13905             pkg.setCodePath(afterCodeFile.getAbsolutePath());
13906             pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13907                     afterCodeFile, pkg.baseCodePath));
13908             pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13909                     afterCodeFile, pkg.splitCodePaths));
13910
13911             // Reflect the rename in app info
13912             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13913             pkg.setApplicationInfoCodePath(pkg.codePath);
13914             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13915             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13916             pkg.setApplicationInfoResourcePath(pkg.codePath);
13917             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13918             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13919
13920             return true;
13921         }
13922
13923         private void setMountPath(String mountPath) {
13924             final File mountFile = new File(mountPath);
13925
13926             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
13927             if (monolithicFile.exists()) {
13928                 packagePath = monolithicFile.getAbsolutePath();
13929                 if (isFwdLocked()) {
13930                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
13931                 } else {
13932                     resourcePath = packagePath;
13933                 }
13934             } else {
13935                 packagePath = mountFile.getAbsolutePath();
13936                 resourcePath = packagePath;
13937             }
13938         }
13939
13940         int doPostInstall(int status, int uid) {
13941             if (status != PackageManager.INSTALL_SUCCEEDED) {
13942                 cleanUp();
13943             } else {
13944                 final int groupOwner;
13945                 final String protectedFile;
13946                 if (isFwdLocked()) {
13947                     groupOwner = UserHandle.getSharedAppGid(uid);
13948                     protectedFile = RES_FILE_NAME;
13949                 } else {
13950                     groupOwner = -1;
13951                     protectedFile = null;
13952                 }
13953
13954                 if (uid < Process.FIRST_APPLICATION_UID
13955                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
13956                     Slog.e(TAG, "Failed to finalize " + cid);
13957                     PackageHelper.destroySdDir(cid);
13958                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13959                 }
13960
13961                 boolean mounted = PackageHelper.isContainerMounted(cid);
13962                 if (!mounted) {
13963                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
13964                 }
13965             }
13966             return status;
13967         }
13968
13969         private void cleanUp() {
13970             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
13971
13972             // Destroy secure container
13973             PackageHelper.destroySdDir(cid);
13974         }
13975
13976         private List<String> getAllCodePaths() {
13977             final File codeFile = new File(getCodePath());
13978             if (codeFile != null && codeFile.exists()) {
13979                 try {
13980                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
13981                     return pkg.getAllCodePaths();
13982                 } catch (PackageParserException e) {
13983                     // Ignored; we tried our best
13984                 }
13985             }
13986             return Collections.EMPTY_LIST;
13987         }
13988
13989         void cleanUpResourcesLI() {
13990             // Enumerate all code paths before deleting
13991             cleanUpResourcesLI(getAllCodePaths());
13992         }
13993
13994         private void cleanUpResourcesLI(List<String> allCodePaths) {
13995             cleanUp();
13996             removeDexFiles(allCodePaths, instructionSets);
13997         }
13998
13999         String getPackageName() {
14000             return getAsecPackageName(cid);
14001         }
14002
14003         boolean doPostDeleteLI(boolean delete) {
14004             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
14005             final List<String> allCodePaths = getAllCodePaths();
14006             boolean mounted = PackageHelper.isContainerMounted(cid);
14007             if (mounted) {
14008                 // Unmount first
14009                 if (PackageHelper.unMountSdDir(cid)) {
14010                     mounted = false;
14011                 }
14012             }
14013             if (!mounted && delete) {
14014                 cleanUpResourcesLI(allCodePaths);
14015             }
14016             return !mounted;
14017         }
14018
14019         @Override
14020         int doPreCopy() {
14021             if (isFwdLocked()) {
14022                 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
14023                         MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
14024                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
14025                 }
14026             }
14027
14028             return PackageManager.INSTALL_SUCCEEDED;
14029         }
14030
14031         @Override
14032         int doPostCopy(int uid) {
14033             if (isFwdLocked()) {
14034                 if (uid < Process.FIRST_APPLICATION_UID
14035                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
14036                                 RES_FILE_NAME)) {
14037                     Slog.e(TAG, "Failed to finalize " + cid);
14038                     PackageHelper.destroySdDir(cid);
14039                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
14040                 }
14041             }
14042
14043             return PackageManager.INSTALL_SUCCEEDED;
14044         }
14045     }
14046
14047     /**
14048      * Logic to handle movement of existing installed applications.
14049      */
14050     class MoveInstallArgs extends InstallArgs {
14051         private File codeFile;
14052         private File resourceFile;
14053
14054         /** New install */
14055         MoveInstallArgs(InstallParams params) {
14056             super(params.origin, params.move, params.observer, params.installFlags,
14057                     params.installerPackageName, params.volumeUuid,
14058                     params.getUser(), null /* instruction sets */, params.packageAbiOverride,
14059                     params.grantedRuntimePermissions,
14060                     params.traceMethod, params.traceCookie, params.certificates);
14061         }
14062
14063         int copyApk(IMediaContainerService imcs, boolean temp) {
14064             if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
14065                     + move.fromUuid + " to " + move.toUuid);
14066             synchronized (mInstaller) {
14067                 try {
14068                     mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
14069                             move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
14070                 } catch (InstallerException e) {
14071                     Slog.w(TAG, "Failed to move app", e);
14072                     return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14073                 }
14074             }
14075
14076             codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
14077             resourceFile = codeFile;
14078             if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
14079
14080             return PackageManager.INSTALL_SUCCEEDED;
14081         }
14082
14083         int doPreInstall(int status) {
14084             if (status != PackageManager.INSTALL_SUCCEEDED) {
14085                 cleanUp(move.toUuid);
14086             }
14087             return status;
14088         }
14089
14090         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
14091             if (status != PackageManager.INSTALL_SUCCEEDED) {
14092                 cleanUp(move.toUuid);
14093                 return false;
14094             }
14095
14096             // Reflect the move in app info
14097             pkg.setApplicationVolumeUuid(pkg.volumeUuid);
14098             pkg.setApplicationInfoCodePath(pkg.codePath);
14099             pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
14100             pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
14101             pkg.setApplicationInfoResourcePath(pkg.codePath);
14102             pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
14103             pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
14104
14105             return true;
14106         }
14107
14108         int doPostInstall(int status, int uid) {
14109             if (status == PackageManager.INSTALL_SUCCEEDED) {
14110                 cleanUp(move.fromUuid);
14111             } else {
14112                 cleanUp(move.toUuid);
14113             }
14114             return status;
14115         }
14116
14117         @Override
14118         String getCodePath() {
14119             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
14120         }
14121
14122         @Override
14123         String getResourcePath() {
14124             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
14125         }
14126
14127         private boolean cleanUp(String volumeUuid) {
14128             final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
14129                     move.dataAppName);
14130             Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
14131             final int[] userIds = sUserManager.getUserIds();
14132             synchronized (mInstallLock) {
14133                 // Clean up both app data and code
14134                 // All package moves are frozen until finished
14135                 for (int userId : userIds) {
14136                     try {
14137                         mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
14138                                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
14139                     } catch (InstallerException e) {
14140                         Slog.w(TAG, String.valueOf(e));
14141                     }
14142                 }
14143                 removeCodePathLI(codeFile);
14144             }
14145             return true;
14146         }
14147
14148         void cleanUpResourcesLI() {
14149             throw new UnsupportedOperationException();
14150         }
14151
14152         boolean doPostDeleteLI(boolean delete) {
14153             throw new UnsupportedOperationException();
14154         }
14155     }
14156
14157     static String getAsecPackageName(String packageCid) {
14158         int idx = packageCid.lastIndexOf("-");
14159         if (idx == -1) {
14160             return packageCid;
14161         }
14162         return packageCid.substring(0, idx);
14163     }
14164
14165     // Utility method used to create code paths based on package name and available index.
14166     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
14167         String idxStr = "";
14168         int idx = 1;
14169         // Fall back to default value of idx=1 if prefix is not
14170         // part of oldCodePath
14171         if (oldCodePath != null) {
14172             String subStr = oldCodePath;
14173             // Drop the suffix right away
14174             if (suffix != null && subStr.endsWith(suffix)) {
14175                 subStr = subStr.substring(0, subStr.length() - suffix.length());
14176             }
14177             // If oldCodePath already contains prefix find out the
14178             // ending index to either increment or decrement.
14179             int sidx = subStr.lastIndexOf(prefix);
14180             if (sidx != -1) {
14181                 subStr = subStr.substring(sidx + prefix.length());
14182                 if (subStr != null) {
14183                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
14184                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
14185                     }
14186                     try {
14187                         idx = Integer.parseInt(subStr);
14188                         if (idx <= 1) {
14189                             idx++;
14190                         } else {
14191                             idx--;
14192                         }
14193                     } catch(NumberFormatException e) {
14194                     }
14195                 }
14196             }
14197         }
14198         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
14199         return prefix + idxStr;
14200     }
14201
14202     private File getNextCodePath(File targetDir, String packageName) {
14203         int suffix = 1;
14204         File result;
14205         do {
14206             result = new File(targetDir, packageName + "-" + suffix);
14207             suffix++;
14208         } while (result.exists());
14209         return result;
14210     }
14211
14212     // Utility method that returns the relative package path with respect
14213     // to the installation directory. Like say for /data/data/com.test-1.apk
14214     // string com.test-1 is returned.
14215     static String deriveCodePathName(String codePath) {
14216         if (codePath == null) {
14217             return null;
14218         }
14219         final File codeFile = new File(codePath);
14220         final String name = codeFile.getName();
14221         if (codeFile.isDirectory()) {
14222             return name;
14223         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
14224             final int lastDot = name.lastIndexOf('.');
14225             return name.substring(0, lastDot);
14226         } else {
14227             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
14228             return null;
14229         }
14230     }
14231
14232     static class PackageInstalledInfo {
14233         String name;
14234         int uid;
14235         // The set of users that originally had this package installed.
14236         int[] origUsers;
14237         // The set of users that now have this package installed.
14238         int[] newUsers;
14239         PackageParser.Package pkg;
14240         int returnCode;
14241         String returnMsg;
14242         PackageRemovedInfo removedInfo;
14243         ArrayMap<String, PackageInstalledInfo> addedChildPackages;
14244
14245         public void setError(int code, String msg) {
14246             setReturnCode(code);
14247             setReturnMessage(msg);
14248             Slog.w(TAG, msg);
14249         }
14250
14251         public void setError(String msg, PackageParserException e) {
14252             setReturnCode(e.error);
14253             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
14254             Slog.w(TAG, msg, e);
14255         }
14256
14257         public void setError(String msg, PackageManagerException e) {
14258             returnCode = e.error;
14259             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
14260             Slog.w(TAG, msg, e);
14261         }
14262
14263         public void setReturnCode(int returnCode) {
14264             this.returnCode = returnCode;
14265             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
14266             for (int i = 0; i < childCount; i++) {
14267                 addedChildPackages.valueAt(i).returnCode = returnCode;
14268             }
14269         }
14270
14271         private void setReturnMessage(String returnMsg) {
14272             this.returnMsg = returnMsg;
14273             final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
14274             for (int i = 0; i < childCount; i++) {
14275                 addedChildPackages.valueAt(i).returnMsg = returnMsg;
14276             }
14277         }
14278
14279         // In some error cases we want to convey more info back to the observer
14280         String origPackage;
14281         String origPermission;
14282     }
14283
14284     /*
14285      * Install a non-existing package.
14286      */
14287     private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
14288             int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
14289             PackageInstalledInfo res) {
14290         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
14291
14292         // Remember this for later, in case we need to rollback this install
14293         String pkgName = pkg.packageName;
14294
14295         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
14296
14297         synchronized(mPackages) {
14298             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
14299                 // A package with the same name is already installed, though
14300                 // it has been renamed to an older name.  The package we
14301                 // are trying to install should be installed as an update to
14302                 // the existing one, but that has not been requested, so bail.
14303                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
14304                         + " without first uninstalling package running as "
14305                         + mSettings.mRenamedPackages.get(pkgName));
14306                 return;
14307             }
14308             if (mPackages.containsKey(pkgName)) {
14309                 // Don't allow installation over an existing package with the same name.
14310                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
14311                         + " without first uninstalling.");
14312                 return;
14313             }
14314         }
14315
14316         try {
14317             PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
14318                     System.currentTimeMillis(), user);
14319
14320             updateSettingsLI(newPackage, installerPackageName, null, res, user);
14321
14322             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14323                 prepareAppDataAfterInstallLIF(newPackage);
14324
14325             } else {
14326                 // Remove package from internal structures, but keep around any
14327                 // data that might have already existed
14328                 deletePackageLIF(pkgName, UserHandle.ALL, false, null,
14329                         PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
14330             }
14331         } catch (PackageManagerException e) {
14332             res.setError("Package couldn't be installed in " + pkg.codePath, e);
14333         }
14334
14335         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14336     }
14337
14338     private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
14339         // Can't rotate keys during boot or if sharedUser.
14340         if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
14341                 || !oldPs.keySetData.isUsingUpgradeKeySets()) {
14342             return false;
14343         }
14344         // app is using upgradeKeySets; make sure all are valid
14345         KeySetManagerService ksms = mSettings.mKeySetManagerService;
14346         long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
14347         for (int i = 0; i < upgradeKeySets.length; i++) {
14348             if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
14349                 Slog.wtf(TAG, "Package "
14350                          + (oldPs.name != null ? oldPs.name : "<null>")
14351                          + " contains upgrade-key-set reference to unknown key-set: "
14352                          + upgradeKeySets[i]
14353                          + " reverting to signatures check.");
14354                 return false;
14355             }
14356         }
14357         return true;
14358     }
14359
14360     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
14361         // Upgrade keysets are being used.  Determine if new package has a superset of the
14362         // required keys.
14363         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
14364         KeySetManagerService ksms = mSettings.mKeySetManagerService;
14365         for (int i = 0; i < upgradeKeySets.length; i++) {
14366             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
14367             if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
14368                 return true;
14369             }
14370         }
14371         return false;
14372     }
14373
14374     private static void updateDigest(MessageDigest digest, File file) throws IOException {
14375         try (DigestInputStream digestStream =
14376                 new DigestInputStream(new FileInputStream(file), digest)) {
14377             while (digestStream.read() != -1) {} // nothing to do; just plow through the file
14378         }
14379     }
14380
14381     private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
14382             UserHandle user, String installerPackageName, PackageInstalledInfo res) {
14383         final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
14384
14385         final PackageParser.Package oldPackage;
14386         final String pkgName = pkg.packageName;
14387         final int[] allUsers;
14388         final int[] installedUsers;
14389
14390         synchronized(mPackages) {
14391             oldPackage = mPackages.get(pkgName);
14392             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
14393
14394             // don't allow upgrade to target a release SDK from a pre-release SDK
14395             final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
14396                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14397             final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
14398                     == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14399             if (oldTargetsPreRelease
14400                     && !newTargetsPreRelease
14401                     && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
14402                 Slog.w(TAG, "Can't install package targeting released sdk");
14403                 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
14404                 return;
14405             }
14406
14407             // don't allow an upgrade from full to ephemeral
14408             final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
14409             if (isEphemeral && !oldIsEphemeral) {
14410                 // can't downgrade from full to ephemeral
14411                 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
14412                 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
14413                 return;
14414             }
14415
14416             // verify signatures are valid
14417             final PackageSetting ps = mSettings.mPackages.get(pkgName);
14418             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
14419                 if (!checkUpgradeKeySetLP(ps, pkg)) {
14420                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14421                             "New package not signed by keys specified by upgrade-keysets: "
14422                                     + pkgName);
14423                     return;
14424                 }
14425             } else {
14426                 // default to original signature matching
14427                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
14428                         != PackageManager.SIGNATURE_MATCH) {
14429                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14430                             "New package has a different signature: " + pkgName);
14431                     return;
14432                 }
14433             }
14434
14435             // don't allow a system upgrade unless the upgrade hash matches
14436             if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
14437                 byte[] digestBytes = null;
14438                 try {
14439                     final MessageDigest digest = MessageDigest.getInstance("SHA-512");
14440                     updateDigest(digest, new File(pkg.baseCodePath));
14441                     if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
14442                         for (String path : pkg.splitCodePaths) {
14443                             updateDigest(digest, new File(path));
14444                         }
14445                     }
14446                     digestBytes = digest.digest();
14447                 } catch (NoSuchAlgorithmException | IOException e) {
14448                     res.setError(INSTALL_FAILED_INVALID_APK,
14449                             "Could not compute hash: " + pkgName);
14450                     return;
14451                 }
14452                 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
14453                     res.setError(INSTALL_FAILED_INVALID_APK,
14454                             "New package fails restrict-update check: " + pkgName);
14455                     return;
14456                 }
14457                 // retain upgrade restriction
14458                 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
14459             }
14460
14461             // Check for shared user id changes
14462             String invalidPackageName =
14463                     getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
14464             if (invalidPackageName != null) {
14465                 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
14466                         "Package " + invalidPackageName + " tried to change user "
14467                                 + oldPackage.mSharedUserId);
14468                 return;
14469             }
14470
14471             // In case of rollback, remember per-user/profile install state
14472             allUsers = sUserManager.getUserIds();
14473             installedUsers = ps.queryInstalledUsers(allUsers, true);
14474         }
14475
14476         // Update what is removed
14477         res.removedInfo = new PackageRemovedInfo();
14478         res.removedInfo.uid = oldPackage.applicationInfo.uid;
14479         res.removedInfo.removedPackage = oldPackage.packageName;
14480         res.removedInfo.isUpdate = true;
14481         res.removedInfo.origUsers = installedUsers;
14482         final int childCount = (oldPackage.childPackages != null)
14483                 ? oldPackage.childPackages.size() : 0;
14484         for (int i = 0; i < childCount; i++) {
14485             boolean childPackageUpdated = false;
14486             PackageParser.Package childPkg = oldPackage.childPackages.get(i);
14487             if (res.addedChildPackages != null) {
14488                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
14489                 if (childRes != null) {
14490                     childRes.removedInfo.uid = childPkg.applicationInfo.uid;
14491                     childRes.removedInfo.removedPackage = childPkg.packageName;
14492                     childRes.removedInfo.isUpdate = true;
14493                     childPackageUpdated = true;
14494                 }
14495             }
14496             if (!childPackageUpdated) {
14497                 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
14498                 childRemovedRes.removedPackage = childPkg.packageName;
14499                 childRemovedRes.isUpdate = false;
14500                 childRemovedRes.dataRemoved = true;
14501                 synchronized (mPackages) {
14502                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
14503                     if (childPs != null) {
14504                         childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
14505                     }
14506                 }
14507                 if (res.removedInfo.removedChildPackages == null) {
14508                     res.removedInfo.removedChildPackages = new ArrayMap<>();
14509                 }
14510                 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
14511             }
14512         }
14513
14514         boolean sysPkg = (isSystemApp(oldPackage));
14515         if (sysPkg) {
14516             // Set the system/privileged flags as needed
14517             final boolean privileged =
14518                     (oldPackage.applicationInfo.privateFlags
14519                             & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
14520             final int systemPolicyFlags = policyFlags
14521                     | PackageParser.PARSE_IS_SYSTEM
14522                     | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
14523
14524             replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
14525                     user, allUsers, installerPackageName, res);
14526         } else {
14527             replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
14528                     user, allUsers, installerPackageName, res);
14529         }
14530     }
14531
14532     public List<String> getPreviousCodePaths(String packageName) {
14533         final PackageSetting ps = mSettings.mPackages.get(packageName);
14534         final List<String> result = new ArrayList<String>();
14535         if (ps != null && ps.oldCodePaths != null) {
14536             result.addAll(ps.oldCodePaths);
14537         }
14538         return result;
14539     }
14540
14541     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
14542             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14543             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14544         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
14545                 + deletedPackage);
14546
14547         String pkgName = deletedPackage.packageName;
14548         boolean deletedPkg = true;
14549         boolean addedPkg = false;
14550         boolean updatedSettings = false;
14551         final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
14552         final int deleteFlags = PackageManager.DELETE_KEEP_DATA
14553                 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
14554
14555         final long origUpdateTime = (pkg.mExtras != null)
14556                 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
14557
14558         // First delete the existing package while retaining the data directory
14559         if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14560                 res.removedInfo, true, pkg)) {
14561             // If the existing package wasn't successfully deleted
14562             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
14563             deletedPkg = false;
14564         } else {
14565             // Successfully deleted the old package; proceed with replace.
14566
14567             // If deleted package lived in a container, give users a chance to
14568             // relinquish resources before killing.
14569             if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
14570                 if (DEBUG_INSTALL) {
14571                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
14572                 }
14573                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
14574                 final ArrayList<String> pkgList = new ArrayList<String>(1);
14575                 pkgList.add(deletedPackage.applicationInfo.packageName);
14576                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
14577             }
14578
14579             clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14580                     | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14581             clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14582
14583             try {
14584                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
14585                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
14586                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14587
14588                 // Update the in-memory copy of the previous code paths.
14589                 PackageSetting ps = mSettings.mPackages.get(pkgName);
14590                 if (!killApp) {
14591                     if (ps.oldCodePaths == null) {
14592                         ps.oldCodePaths = new ArraySet<>();
14593                     }
14594                     Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
14595                     if (deletedPackage.splitCodePaths != null) {
14596                         Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
14597                     }
14598                 } else {
14599                     ps.oldCodePaths = null;
14600                 }
14601                 if (ps.childPackageNames != null) {
14602                     for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
14603                         final String childPkgName = ps.childPackageNames.get(i);
14604                         final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
14605                         childPs.oldCodePaths = ps.oldCodePaths;
14606                     }
14607                 }
14608                 prepareAppDataAfterInstallLIF(newPackage);
14609                 addedPkg = true;
14610             } catch (PackageManagerException e) {
14611                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
14612             }
14613         }
14614
14615         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14616             if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
14617
14618             // Revert all internal state mutations and added folders for the failed install
14619             if (addedPkg) {
14620                 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14621                         res.removedInfo, true, null);
14622             }
14623
14624             // Restore the old package
14625             if (deletedPkg) {
14626                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
14627                 File restoreFile = new File(deletedPackage.codePath);
14628                 // Parse old package
14629                 boolean oldExternal = isExternal(deletedPackage);
14630                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
14631                         (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
14632                         (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
14633                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
14634                 try {
14635                     scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
14636                             null);
14637                 } catch (PackageManagerException e) {
14638                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
14639                             + e.getMessage());
14640                     return;
14641                 }
14642
14643                 synchronized (mPackages) {
14644                     // Ensure the installer package name up to date
14645                     setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14646
14647                     // Update permissions for restored package
14648                     updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14649
14650                     mSettings.writeLPr();
14651                 }
14652
14653                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
14654             }
14655         } else {
14656             synchronized (mPackages) {
14657                 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName);
14658                 if (ps != null) {
14659                     res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
14660                     if (res.removedInfo.removedChildPackages != null) {
14661                         final int childCount = res.removedInfo.removedChildPackages.size();
14662                         // Iterate in reverse as we may modify the collection
14663                         for (int i = childCount - 1; i >= 0; i--) {
14664                             String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
14665                             if (res.addedChildPackages.containsKey(childPackageName)) {
14666                                 res.removedInfo.removedChildPackages.removeAt(i);
14667                             } else {
14668                                 PackageRemovedInfo childInfo = res.removedInfo
14669                                         .removedChildPackages.valueAt(i);
14670                                 childInfo.removedForAllUsers = mPackages.get(
14671                                         childInfo.removedPackage) == null;
14672                             }
14673                         }
14674                     }
14675                 }
14676             }
14677         }
14678     }
14679
14680     private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
14681             PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14682             int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14683         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
14684                 + ", old=" + deletedPackage);
14685
14686         final boolean disabledSystem;
14687
14688         // Remove existing system package
14689         removePackageLI(deletedPackage, true);
14690
14691         synchronized (mPackages) {
14692             disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
14693         }
14694         if (!disabledSystem) {
14695             // We didn't need to disable the .apk as a current system package,
14696             // which means we are replacing another update that is already
14697             // installed.  We need to make sure to delete the older one's .apk.
14698             res.removedInfo.args = createInstallArgsForExisting(0,
14699                     deletedPackage.applicationInfo.getCodePath(),
14700                     deletedPackage.applicationInfo.getResourcePath(),
14701                     getAppDexInstructionSets(deletedPackage.applicationInfo));
14702         } else {
14703             res.removedInfo.args = null;
14704         }
14705
14706         // Successfully disabled the old package. Now proceed with re-installation
14707         clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14708                 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14709         clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14710
14711         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14712         pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
14713                 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
14714
14715         PackageParser.Package newPackage = null;
14716         try {
14717             // Add the package to the internal data structures
14718             newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
14719
14720             // Set the update and install times
14721             PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
14722             setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
14723                     System.currentTimeMillis());
14724
14725             // Update the package dynamic state if succeeded
14726             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14727                 // Now that the install succeeded make sure we remove data
14728                 // directories for any child package the update removed.
14729                 final int deletedChildCount = (deletedPackage.childPackages != null)
14730                         ? deletedPackage.childPackages.size() : 0;
14731                 final int newChildCount = (newPackage.childPackages != null)
14732                         ? newPackage.childPackages.size() : 0;
14733                 for (int i = 0; i < deletedChildCount; i++) {
14734                     PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
14735                     boolean childPackageDeleted = true;
14736                     for (int j = 0; j < newChildCount; j++) {
14737                         PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
14738                         if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
14739                             childPackageDeleted = false;
14740                             break;
14741                         }
14742                     }
14743                     if (childPackageDeleted) {
14744                         PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
14745                                 deletedChildPkg.packageName);
14746                         if (ps != null && res.removedInfo.removedChildPackages != null) {
14747                             PackageRemovedInfo removedChildRes = res.removedInfo
14748                                     .removedChildPackages.get(deletedChildPkg.packageName);
14749                             removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
14750                             removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
14751                         }
14752                     }
14753                 }
14754
14755                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14756                 prepareAppDataAfterInstallLIF(newPackage);
14757             }
14758         } catch (PackageManagerException e) {
14759             res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
14760             res.setError("Package couldn't be installed in " + pkg.codePath, e);
14761         }
14762
14763         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14764             // Re installation failed. Restore old information
14765             // Remove new pkg information
14766             if (newPackage != null) {
14767                 removeInstalledPackageLI(newPackage, true);
14768             }
14769             // Add back the old system package
14770             try {
14771                 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
14772             } catch (PackageManagerException e) {
14773                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
14774             }
14775
14776             synchronized (mPackages) {
14777                 if (disabledSystem) {
14778                     enableSystemPackageLPw(deletedPackage);
14779                 }
14780
14781                 // Ensure the installer package name up to date
14782                 setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14783
14784                 // Update permissions for restored package
14785                 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14786
14787                 mSettings.writeLPr();
14788             }
14789
14790             Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
14791                     + " after failed upgrade");
14792         }
14793     }
14794
14795     /**
14796      * Checks whether the parent or any of the child packages have a change shared
14797      * user. For a package to be a valid update the shred users of the parent and
14798      * the children should match. We may later support changing child shared users.
14799      * @param oldPkg The updated package.
14800      * @param newPkg The update package.
14801      * @return The shared user that change between the versions.
14802      */
14803     private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
14804             PackageParser.Package newPkg) {
14805         // Check parent shared user
14806         if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
14807             return newPkg.packageName;
14808         }
14809         // Check child shared users
14810         final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14811         final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
14812         for (int i = 0; i < newChildCount; i++) {
14813             PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
14814             // If this child was present, did it have the same shared user?
14815             for (int j = 0; j < oldChildCount; j++) {
14816                 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
14817                 if (newChildPkg.packageName.equals(oldChildPkg.packageName)
14818                         && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
14819                     return newChildPkg.packageName;
14820                 }
14821             }
14822         }
14823         return null;
14824     }
14825
14826     private void removeNativeBinariesLI(PackageSetting ps) {
14827         // Remove the lib path for the parent package
14828         if (ps != null) {
14829             NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
14830             // Remove the lib path for the child packages
14831             final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
14832             for (int i = 0; i < childCount; i++) {
14833                 PackageSetting childPs = null;
14834                 synchronized (mPackages) {
14835                     childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
14836                 }
14837                 if (childPs != null) {
14838                     NativeLibraryHelper.removeNativeBinariesLI(childPs
14839                             .legacyNativeLibraryPathString);
14840                 }
14841             }
14842         }
14843     }
14844
14845     private void enableSystemPackageLPw(PackageParser.Package pkg) {
14846         // Enable the parent package
14847         mSettings.enableSystemPackageLPw(pkg.packageName);
14848         // Enable the child packages
14849         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14850         for (int i = 0; i < childCount; i++) {
14851             PackageParser.Package childPkg = pkg.childPackages.get(i);
14852             mSettings.enableSystemPackageLPw(childPkg.packageName);
14853         }
14854     }
14855
14856     private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
14857             PackageParser.Package newPkg) {
14858         // Disable the parent package (parent always replaced)
14859         boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
14860         // Disable the child packages
14861         final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14862         for (int i = 0; i < childCount; i++) {
14863             PackageParser.Package childPkg = oldPkg.childPackages.get(i);
14864             final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
14865             disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
14866         }
14867         return disabled;
14868     }
14869
14870     private void setInstallerPackageNameLPw(PackageParser.Package pkg,
14871             String installerPackageName) {
14872         // Enable the parent package
14873         mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
14874         // Enable the child packages
14875         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14876         for (int i = 0; i < childCount; i++) {
14877             PackageParser.Package childPkg = pkg.childPackages.get(i);
14878             mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
14879         }
14880     }
14881
14882     private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
14883         // Collect all used permissions in the UID
14884         ArraySet<String> usedPermissions = new ArraySet<>();
14885         final int packageCount = su.packages.size();
14886         for (int i = 0; i < packageCount; i++) {
14887             PackageSetting ps = su.packages.valueAt(i);
14888             if (ps.pkg == null) {
14889                 continue;
14890             }
14891             final int requestedPermCount = ps.pkg.requestedPermissions.size();
14892             for (int j = 0; j < requestedPermCount; j++) {
14893                 String permission = ps.pkg.requestedPermissions.get(j);
14894                 BasePermission bp = mSettings.mPermissions.get(permission);
14895                 if (bp != null) {
14896                     usedPermissions.add(permission);
14897                 }
14898             }
14899         }
14900
14901         PermissionsState permissionsState = su.getPermissionsState();
14902         // Prune install permissions
14903         List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
14904         final int installPermCount = installPermStates.size();
14905         for (int i = installPermCount - 1; i >= 0;  i--) {
14906             PermissionState permissionState = installPermStates.get(i);
14907             if (!usedPermissions.contains(permissionState.getName())) {
14908                 BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14909                 if (bp != null) {
14910                     permissionsState.revokeInstallPermission(bp);
14911                     permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
14912                             PackageManager.MASK_PERMISSION_FLAGS, 0);
14913                 }
14914             }
14915         }
14916
14917         int[] runtimePermissionChangedUserIds = EmptyArray.INT;
14918
14919         // Prune runtime permissions
14920         for (int userId : allUserIds) {
14921             List<PermissionState> runtimePermStates = permissionsState
14922                     .getRuntimePermissionStates(userId);
14923             final int runtimePermCount = runtimePermStates.size();
14924             for (int i = runtimePermCount - 1; i >= 0; i--) {
14925                 PermissionState permissionState = runtimePermStates.get(i);
14926                 if (!usedPermissions.contains(permissionState.getName())) {
14927                     BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14928                     if (bp != null) {
14929                         permissionsState.revokeRuntimePermission(bp, userId);
14930                         permissionsState.updatePermissionFlags(bp, userId,
14931                                 PackageManager.MASK_PERMISSION_FLAGS, 0);
14932                         runtimePermissionChangedUserIds = ArrayUtils.appendInt(
14933                                 runtimePermissionChangedUserIds, userId);
14934                     }
14935                 }
14936             }
14937         }
14938
14939         return runtimePermissionChangedUserIds;
14940     }
14941
14942     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
14943             int[] allUsers, PackageInstalledInfo res, UserHandle user) {
14944         // Update the parent package setting
14945         updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
14946                 res, user);
14947         // Update the child packages setting
14948         final int childCount = (newPackage.childPackages != null)
14949                 ? newPackage.childPackages.size() : 0;
14950         for (int i = 0; i < childCount; i++) {
14951             PackageParser.Package childPackage = newPackage.childPackages.get(i);
14952             PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
14953             updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
14954                     childRes.origUsers, childRes, user);
14955         }
14956     }
14957
14958     private void updateSettingsInternalLI(PackageParser.Package newPackage,
14959             String installerPackageName, int[] allUsers, int[] installedForUsers,
14960             PackageInstalledInfo res, UserHandle user) {
14961         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
14962
14963         String pkgName = newPackage.packageName;
14964         synchronized (mPackages) {
14965             //write settings. the installStatus will be incomplete at this stage.
14966             //note that the new package setting would have already been
14967             //added to mPackages. It hasn't been persisted yet.
14968             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
14969             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
14970             mSettings.writeLPr();
14971             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14972         }
14973
14974         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
14975         synchronized (mPackages) {
14976             updatePermissionsLPw(newPackage.packageName, newPackage,
14977                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
14978                             ? UPDATE_PERMISSIONS_ALL : 0));
14979             // For system-bundled packages, we assume that installing an upgraded version
14980             // of the package implies that the user actually wants to run that new code,
14981             // so we enable the package.
14982             PackageSetting ps = mSettings.mPackages.get(pkgName);
14983             final int userId = user.getIdentifier();
14984             if (ps != null) {
14985                 if (isSystemApp(newPackage)) {
14986                     if (DEBUG_INSTALL) {
14987                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
14988                     }
14989                     // Enable system package for requested users
14990                     if (res.origUsers != null) {
14991                         for (int origUserId : res.origUsers) {
14992                             if (userId == UserHandle.USER_ALL || userId == origUserId) {
14993                                 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
14994                                         origUserId, installerPackageName);
14995                             }
14996                         }
14997                     }
14998                     // Also convey the prior install/uninstall state
14999                     if (allUsers != null && installedForUsers != null) {
15000                         for (int currentUserId : allUsers) {
15001                             final boolean installed = ArrayUtils.contains(
15002                                     installedForUsers, currentUserId);
15003                             if (DEBUG_INSTALL) {
15004                                 Slog.d(TAG, "    user " + currentUserId + " => " + installed);
15005                             }
15006                             ps.setInstalled(installed, currentUserId);
15007                         }
15008                         // these install state changes will be persisted in the
15009                         // upcoming call to mSettings.writeLPr().
15010                     }
15011                 }
15012                 // It's implied that when a user requests installation, they want the app to be
15013                 // installed and enabled.
15014                 if (userId != UserHandle.USER_ALL) {
15015                     ps.setInstalled(true, userId);
15016                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
15017                 }
15018             }
15019             res.name = pkgName;
15020             res.uid = newPackage.applicationInfo.uid;
15021             res.pkg = newPackage;
15022             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
15023             mSettings.setInstallerPackageName(pkgName, installerPackageName);
15024             res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15025             //to update install status
15026             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
15027             mSettings.writeLPr();
15028             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15029         }
15030
15031         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15032     }
15033
15034     private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
15035         try {
15036             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
15037             installPackageLI(args, res);
15038         } finally {
15039             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15040         }
15041     }
15042
15043     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
15044         final int installFlags = args.installFlags;
15045         final String installerPackageName = args.installerPackageName;
15046         final String volumeUuid = args.volumeUuid;
15047         final File tmpPackageFile = new File(args.getCodePath());
15048         final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
15049         final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
15050                 || (args.volumeUuid != null));
15051         final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
15052         final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
15053         boolean replace = false;
15054         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
15055         if (args.move != null) {
15056             // moving a complete application; perform an initial scan on the new install location
15057             scanFlags |= SCAN_INITIAL;
15058         }
15059         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
15060             scanFlags |= SCAN_DONT_KILL_APP;
15061         }
15062
15063         // Result object to be returned
15064         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15065
15066         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
15067
15068         // Sanity check
15069         if (ephemeral && (forwardLocked || onExternal)) {
15070             Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
15071                     + " external=" + onExternal);
15072             res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
15073             return;
15074         }
15075
15076         // Retrieve PackageSettings and parse package
15077         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
15078                 | PackageParser.PARSE_ENFORCE_CODE
15079                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
15080                 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
15081                 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0)
15082                 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
15083         PackageParser pp = new PackageParser();
15084         pp.setSeparateProcesses(mSeparateProcesses);
15085         pp.setDisplayMetrics(mMetrics);
15086
15087         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
15088         final PackageParser.Package pkg;
15089         try {
15090             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
15091         } catch (PackageParserException e) {
15092             res.setError("Failed parse during installPackageLI", e);
15093             return;
15094         } finally {
15095             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15096         }
15097
15098         // If we are installing a clustered package add results for the children
15099         if (pkg.childPackages != null) {
15100             synchronized (mPackages) {
15101                 final int childCount = pkg.childPackages.size();
15102                 for (int i = 0; i < childCount; i++) {
15103                     PackageParser.Package childPkg = pkg.childPackages.get(i);
15104                     PackageInstalledInfo childRes = new PackageInstalledInfo();
15105                     childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15106                     childRes.pkg = childPkg;
15107                     childRes.name = childPkg.packageName;
15108                     PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
15109                     if (childPs != null) {
15110                         childRes.origUsers = childPs.queryInstalledUsers(
15111                                 sUserManager.getUserIds(), true);
15112                     }
15113                     if ((mPackages.containsKey(childPkg.packageName))) {
15114                         childRes.removedInfo = new PackageRemovedInfo();
15115                         childRes.removedInfo.removedPackage = childPkg.packageName;
15116                     }
15117                     if (res.addedChildPackages == null) {
15118                         res.addedChildPackages = new ArrayMap<>();
15119                     }
15120                     res.addedChildPackages.put(childPkg.packageName, childRes);
15121                 }
15122             }
15123         }
15124
15125         // If package doesn't declare API override, mark that we have an install
15126         // time CPU ABI override.
15127         if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
15128             pkg.cpuAbiOverride = args.abiOverride;
15129         }
15130
15131         String pkgName = res.name = pkg.packageName;
15132         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
15133             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
15134                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
15135                 return;
15136             }
15137         }
15138
15139         try {
15140             // either use what we've been given or parse directly from the APK
15141             if (args.certificates != null) {
15142                 try {
15143                     PackageParser.populateCertificates(pkg, args.certificates);
15144                 } catch (PackageParserException e) {
15145                     // there was something wrong with the certificates we were given;
15146                     // try to pull them from the APK
15147                     PackageParser.collectCertificates(pkg, parseFlags);
15148                 }
15149             } else {
15150                 PackageParser.collectCertificates(pkg, parseFlags);
15151             }
15152         } catch (PackageParserException e) {
15153             res.setError("Failed collect during installPackageLI", e);
15154             return;
15155         }
15156
15157         // Get rid of all references to package scan path via parser.
15158         pp = null;
15159         String oldCodePath = null;
15160         boolean systemApp = false;
15161         synchronized (mPackages) {
15162             // Check if installing already existing package
15163             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15164                 String oldName = mSettings.mRenamedPackages.get(pkgName);
15165                 if (pkg.mOriginalPackages != null
15166                         && pkg.mOriginalPackages.contains(oldName)
15167                         && mPackages.containsKey(oldName)) {
15168                     // This package is derived from an original package,
15169                     // and this device has been updating from that original
15170                     // name.  We must continue using the original name, so
15171                     // rename the new package here.
15172                     pkg.setPackageName(oldName);
15173                     pkgName = pkg.packageName;
15174                     replace = true;
15175                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
15176                             + oldName + " pkgName=" + pkgName);
15177                 } else if (mPackages.containsKey(pkgName)) {
15178                     // This package, under its official name, already exists
15179                     // on the device; we should replace it.
15180                     replace = true;
15181                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
15182                 }
15183
15184                 // Child packages are installed through the parent package
15185                 if (pkg.parentPackage != null) {
15186                     res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
15187                             "Package " + pkg.packageName + " is child of package "
15188                                     + pkg.parentPackage.parentPackage + ". Child packages "
15189                                     + "can be updated only through the parent package.");
15190                     return;
15191                 }
15192
15193                 if (replace) {
15194                     // Prevent apps opting out from runtime permissions
15195                     PackageParser.Package oldPackage = mPackages.get(pkgName);
15196                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
15197                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
15198                     if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
15199                             && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
15200                         res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
15201                                 "Package " + pkg.packageName + " new target SDK " + newTargetSdk
15202                                         + " doesn't support runtime permissions but the old"
15203                                         + " target SDK " + oldTargetSdk + " does.");
15204                         return;
15205                     }
15206
15207                     // Prevent installing of child packages
15208                     if (oldPackage.parentPackage != null) {
15209                         res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
15210                                 "Package " + pkg.packageName + " is child of package "
15211                                         + oldPackage.parentPackage + ". Child packages "
15212                                         + "can be updated only through the parent package.");
15213                         return;
15214                     }
15215                 }
15216             }
15217
15218             PackageSetting ps = mSettings.mPackages.get(pkgName);
15219             if (ps != null) {
15220                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
15221
15222                 // Quick sanity check that we're signed correctly if updating;
15223                 // we'll check this again later when scanning, but we want to
15224                 // bail early here before tripping over redefined permissions.
15225                 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
15226                     if (!checkUpgradeKeySetLP(ps, pkg)) {
15227                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
15228                                 + pkg.packageName + " upgrade keys do not match the "
15229                                 + "previously installed version");
15230                         return;
15231                     }
15232                 } else {
15233                     try {
15234                         verifySignaturesLP(ps, pkg);
15235                     } catch (PackageManagerException e) {
15236                         res.setError(e.error, e.getMessage());
15237                         return;
15238                     }
15239                 }
15240
15241                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
15242                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
15243                     systemApp = (ps.pkg.applicationInfo.flags &
15244                             ApplicationInfo.FLAG_SYSTEM) != 0;
15245                 }
15246                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
15247             }
15248
15249             // Check whether the newly-scanned package wants to define an already-defined perm
15250             int N = pkg.permissions.size();
15251             for (int i = N-1; i >= 0; i--) {
15252                 PackageParser.Permission perm = pkg.permissions.get(i);
15253                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
15254                 if (bp != null) {
15255                     // If the defining package is signed with our cert, it's okay.  This
15256                     // also includes the "updating the same package" case, of course.
15257                     // "updating same package" could also involve key-rotation.
15258                     final boolean sigsOk;
15259                     if (bp.sourcePackage.equals(pkg.packageName)
15260                             && (bp.packageSetting instanceof PackageSetting)
15261                             && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
15262                                     scanFlags))) {
15263                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
15264                     } else {
15265                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
15266                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
15267                     }
15268                     if (!sigsOk) {
15269                         // If the owning package is the system itself, we log but allow
15270                         // install to proceed; we fail the install on all other permission
15271                         // redefinitions.
15272                         if (!bp.sourcePackage.equals("android")) {
15273                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
15274                                     + pkg.packageName + " attempting to redeclare permission "
15275                                     + perm.info.name + " already owned by " + bp.sourcePackage);
15276                             res.origPermission = perm.info.name;
15277                             res.origPackage = bp.sourcePackage;
15278                             return;
15279                         } else {
15280                             Slog.w(TAG, "Package " + pkg.packageName
15281                                     + " attempting to redeclare system permission "
15282                                     + perm.info.name + "; ignoring new declaration");
15283                             pkg.permissions.remove(i);
15284                         }
15285                     } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
15286                         // Prevent apps to change protection level to dangerous from any other
15287                         // type as this would allow a privilege escalation where an app adds a
15288                         // normal/signature permission in other app's group and later redefines
15289                         // it as dangerous leading to the group auto-grant.
15290                         if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
15291                                 == PermissionInfo.PROTECTION_DANGEROUS) {
15292                             if (bp != null && !bp.isRuntime()) {
15293                                 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
15294                                         + "non-runtime permission " + perm.info.name
15295                                         + " to runtime; keeping old protection level");
15296                                 perm.info.protectionLevel = bp.protectionLevel;
15297                             }
15298                         }
15299                     }
15300                 }
15301             }
15302         }
15303
15304         if (systemApp) {
15305             if (onExternal) {
15306                 // Abort update; system app can't be replaced with app on sdcard
15307                 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
15308                         "Cannot install updates to system apps on sdcard");
15309                 return;
15310             } else if (ephemeral) {
15311                 // Abort update; system app can't be replaced with an ephemeral app
15312                 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
15313                         "Cannot update a system app with an ephemeral app");
15314                 return;
15315             }
15316         }
15317
15318         if (args.move != null) {
15319             // We did an in-place move, so dex is ready to roll
15320             scanFlags |= SCAN_NO_DEX;
15321             scanFlags |= SCAN_MOVE;
15322
15323             synchronized (mPackages) {
15324                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
15325                 if (ps == null) {
15326                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
15327                             "Missing settings for moved package " + pkgName);
15328                 }
15329
15330                 // We moved the entire application as-is, so bring over the
15331                 // previously derived ABI information.
15332                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
15333                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
15334             }
15335
15336         } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
15337             // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
15338             scanFlags |= SCAN_NO_DEX;
15339
15340             try {
15341                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
15342                     args.abiOverride : pkg.cpuAbiOverride);
15343                 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
15344                         true /* extract libs */);
15345             } catch (PackageManagerException pme) {
15346                 Slog.e(TAG, "Error deriving application ABI", pme);
15347                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
15348                 return;
15349             }
15350
15351             // Shared libraries for the package need to be updated.
15352             synchronized (mPackages) {
15353                 try {
15354                     updateSharedLibrariesLPw(pkg, null);
15355                 } catch (PackageManagerException e) {
15356                     Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage());
15357                 }
15358             }
15359             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
15360             // Do not run PackageDexOptimizer through the local performDexOpt
15361             // method because `pkg` may not be in `mPackages` yet.
15362             //
15363             // Also, don't fail application installs if the dexopt step fails.
15364             mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
15365                     null /* instructionSets */, false /* checkProfiles */,
15366                     getCompilerFilterForReason(REASON_INSTALL),
15367                     getOrCreateCompilerPackageStats(pkg));
15368             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15369
15370             // Notify BackgroundDexOptService that the package has been changed.
15371             // If this is an update of a package which used to fail to compile,
15372             // BDOS will remove it from its blacklist.
15373             BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
15374         }
15375
15376         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
15377             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
15378             return;
15379         }
15380
15381         startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
15382
15383         try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
15384                 "installPackageLI")) {
15385             if (replace) {
15386                 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
15387                         installerPackageName, res);
15388             } else {
15389                 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
15390                         args.user, installerPackageName, volumeUuid, res);
15391             }
15392         }
15393         synchronized (mPackages) {
15394             final PackageSetting ps = mSettings.mPackages.get(pkgName);
15395             if (ps != null) {
15396                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
15397             }
15398
15399             final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15400             for (int i = 0; i < childCount; i++) {
15401                 PackageParser.Package childPkg = pkg.childPackages.get(i);
15402                 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15403                 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
15404                 if (childPs != null) {
15405                     childRes.newUsers = childPs.queryInstalledUsers(
15406                             sUserManager.getUserIds(), true);
15407                 }
15408             }
15409         }
15410     }
15411
15412     private void startIntentFilterVerifications(int userId, boolean replacing,
15413             PackageParser.Package pkg) {
15414         if (mIntentFilterVerifierComponent == null) {
15415             Slog.w(TAG, "No IntentFilter verification will not be done as "
15416                     + "there is no IntentFilterVerifier available!");
15417             return;
15418         }
15419
15420         final int verifierUid = getPackageUid(
15421                 mIntentFilterVerifierComponent.getPackageName(),
15422                 MATCH_DEBUG_TRIAGED_MISSING,
15423                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
15424
15425         Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15426         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
15427         mHandler.sendMessage(msg);
15428
15429         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15430         for (int i = 0; i < childCount; i++) {
15431             PackageParser.Package childPkg = pkg.childPackages.get(i);
15432             msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15433             msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
15434             mHandler.sendMessage(msg);
15435         }
15436     }
15437
15438     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
15439             PackageParser.Package pkg) {
15440         int size = pkg.activities.size();
15441         if (size == 0) {
15442             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15443                     "No activity, so no need to verify any IntentFilter!");
15444             return;
15445         }
15446
15447         final boolean hasDomainURLs = hasDomainURLs(pkg);
15448         if (!hasDomainURLs) {
15449             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15450                     "No domain URLs, so no need to verify any IntentFilter!");
15451             return;
15452         }
15453
15454         if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
15455                 + " if any IntentFilter from the " + size
15456                 + " Activities needs verification ...");
15457
15458         int count = 0;
15459         final String packageName = pkg.packageName;
15460
15461         synchronized (mPackages) {
15462             // If this is a new install and we see that we've already run verification for this
15463             // package, we have nothing to do: it means the state was restored from backup.
15464             if (!replacing) {
15465                 IntentFilterVerificationInfo ivi =
15466                         mSettings.getIntentFilterVerificationLPr(packageName);
15467                 if (ivi != null) {
15468                     if (DEBUG_DOMAIN_VERIFICATION) {
15469                         Slog.i(TAG, "Package " + packageName+ " already verified: status="
15470                                 + ivi.getStatusString());
15471                     }
15472                     return;
15473                 }
15474             }
15475
15476             // If any filters need to be verified, then all need to be.
15477             boolean needToVerify = false;
15478             for (PackageParser.Activity a : pkg.activities) {
15479                 for (ActivityIntentInfo filter : a.intents) {
15480                     if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
15481                         if (DEBUG_DOMAIN_VERIFICATION) {
15482                             Slog.d(TAG, "Intent filter needs verification, so processing all filters");
15483                         }
15484                         needToVerify = true;
15485                         break;
15486                     }
15487                 }
15488             }
15489
15490             if (needToVerify) {
15491                 final int verificationId = mIntentFilterVerificationToken++;
15492                 for (PackageParser.Activity a : pkg.activities) {
15493                     for (ActivityIntentInfo filter : a.intents) {
15494                         if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
15495                             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15496                                     "Verification needed for IntentFilter:" + filter.toString());
15497                             mIntentFilterVerifier.addOneIntentFilterVerification(
15498                                     verifierUid, userId, verificationId, filter, packageName);
15499                             count++;
15500                         }
15501                     }
15502                 }
15503             }
15504         }
15505
15506         if (count > 0) {
15507             if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
15508                     + " IntentFilter verification" + (count > 1 ? "s" : "")
15509                     +  " for userId:" + userId);
15510             mIntentFilterVerifier.startVerifications(userId);
15511         } else {
15512             if (DEBUG_DOMAIN_VERIFICATION) {
15513                 Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
15514             }
15515         }
15516     }
15517
15518     private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
15519         final ComponentName cn  = filter.activity.getComponentName();
15520         final String packageName = cn.getPackageName();
15521
15522         IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
15523                 packageName);
15524         if (ivi == null) {
15525             return true;
15526         }
15527         int status = ivi.getStatus();
15528         switch (status) {
15529             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
15530             case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
15531                 return true;
15532
15533             default:
15534                 // Nothing to do
15535                 return false;
15536         }
15537     }
15538
15539     private static boolean isMultiArch(ApplicationInfo info) {
15540         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
15541     }
15542
15543     private static boolean isExternal(PackageParser.Package pkg) {
15544         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15545     }
15546
15547     private static boolean isExternal(PackageSetting ps) {
15548         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15549     }
15550
15551     private static boolean isEphemeral(PackageParser.Package pkg) {
15552         return pkg.applicationInfo.isEphemeralApp();
15553     }
15554
15555     private static boolean isEphemeral(PackageSetting ps) {
15556         return ps.pkg != null && isEphemeral(ps.pkg);
15557     }
15558
15559     private static boolean isSystemApp(PackageParser.Package pkg) {
15560         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
15561     }
15562
15563     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
15564         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15565     }
15566
15567     private static boolean hasDomainURLs(PackageParser.Package pkg) {
15568         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
15569     }
15570
15571     private static boolean isSystemApp(PackageSetting ps) {
15572         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
15573     }
15574
15575     private static boolean isUpdatedSystemApp(PackageSetting ps) {
15576         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
15577     }
15578
15579     private int packageFlagsToInstallFlags(PackageSetting ps) {
15580         int installFlags = 0;
15581         if (isEphemeral(ps)) {
15582             installFlags |= PackageManager.INSTALL_EPHEMERAL;
15583         }
15584         if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
15585             // This existing package was an external ASEC install when we have
15586             // the external flag without a UUID
15587             installFlags |= PackageManager.INSTALL_EXTERNAL;
15588         }
15589         if (ps.isForwardLocked()) {
15590             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
15591         }
15592         return installFlags;
15593     }
15594
15595     private String getVolumeUuidForPackage(PackageParser.Package pkg) {
15596         if (isExternal(pkg)) {
15597             if (TextUtils.isEmpty(pkg.volumeUuid)) {
15598                 return StorageManager.UUID_PRIMARY_PHYSICAL;
15599             } else {
15600                 return pkg.volumeUuid;
15601             }
15602         } else {
15603             return StorageManager.UUID_PRIVATE_INTERNAL;
15604         }
15605     }
15606
15607     private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
15608         if (isExternal(pkg)) {
15609             if (TextUtils.isEmpty(pkg.volumeUuid)) {
15610                 return mSettings.getExternalVersion();
15611             } else {
15612                 return mSettings.findOrCreateVersion(pkg.volumeUuid);
15613             }
15614         } else {
15615             return mSettings.getInternalVersion();
15616         }
15617     }
15618
15619     private void deleteTempPackageFiles() {
15620         final FilenameFilter filter = new FilenameFilter() {
15621             public boolean accept(File dir, String name) {
15622                 return name.startsWith("vmdl") && name.endsWith(".tmp");
15623             }
15624         };
15625         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
15626             file.delete();
15627         }
15628     }
15629
15630     @Override
15631     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
15632             int flags) {
15633         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
15634                 flags);
15635     }
15636
15637     @Override
15638     public void deletePackage(final String packageName,
15639             final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
15640         mContext.enforceCallingOrSelfPermission(
15641                 android.Manifest.permission.DELETE_PACKAGES, null);
15642         Preconditions.checkNotNull(packageName);
15643         Preconditions.checkNotNull(observer);
15644         final int uid = Binder.getCallingUid();
15645         if (!isOrphaned(packageName)
15646                 && !isCallerAllowedToSilentlyUninstall(uid, packageName)) {
15647             try {
15648                 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
15649                 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
15650                 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
15651                 observer.onUserActionRequired(intent);
15652             } catch (RemoteException re) {
15653             }
15654             return;
15655         }
15656         final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
15657         final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
15658         if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
15659             mContext.enforceCallingOrSelfPermission(
15660                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15661                     "deletePackage for user " + userId);
15662         }
15663
15664         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
15665             try {
15666                 observer.onPackageDeleted(packageName,
15667                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
15668             } catch (RemoteException re) {
15669             }
15670             return;
15671         }
15672
15673         if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) {
15674             try {
15675                 observer.onPackageDeleted(packageName,
15676                         PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
15677             } catch (RemoteException re) {
15678             }
15679             return;
15680         }
15681
15682         if (DEBUG_REMOVE) {
15683             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId
15684                     + " deleteAllUsers: " + deleteAllUsers );
15685         }
15686         // Queue up an async operation since the package deletion may take a little while.
15687         mHandler.post(new Runnable() {
15688             public void run() {
15689                 mHandler.removeCallbacks(this);
15690                 int returnCode;
15691                 if (!deleteAllUsers) {
15692                     returnCode = deletePackageX(packageName, userId, deleteFlags);
15693                 } else {
15694                     int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users);
15695                     // If nobody is blocking uninstall, proceed with delete for all users
15696                     if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
15697                         returnCode = deletePackageX(packageName, userId, deleteFlags);
15698                     } else {
15699                         // Otherwise uninstall individually for users with blockUninstalls=false
15700                         final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
15701                         for (int userId : users) {
15702                             if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
15703                                 returnCode = deletePackageX(packageName, userId, userFlags);
15704                                 if (returnCode != PackageManager.DELETE_SUCCEEDED) {
15705                                     Slog.w(TAG, "Package delete failed for user " + userId
15706                                             + ", returnCode " + returnCode);
15707                                 }
15708                             }
15709                         }
15710                         // The app has only been marked uninstalled for certain users.
15711                         // We still need to report that delete was blocked
15712                         returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
15713                     }
15714                 }
15715                 try {
15716                     observer.onPackageDeleted(packageName, returnCode, null);
15717                 } catch (RemoteException e) {
15718                     Log.i(TAG, "Observer no longer exists.");
15719                 } //end catch
15720             } //end run
15721         });
15722     }
15723
15724     private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
15725         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
15726               || callingUid == Process.SYSTEM_UID) {
15727             return true;
15728         }
15729         final int callingUserId = UserHandle.getUserId(callingUid);
15730         // If the caller installed the pkgName, then allow it to silently uninstall.
15731         if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
15732             return true;
15733         }
15734
15735         // Allow package verifier to silently uninstall.
15736         if (mRequiredVerifierPackage != null &&
15737                 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
15738             return true;
15739         }
15740
15741         // Allow package uninstaller to silently uninstall.
15742         if (mRequiredUninstallerPackage != null &&
15743                 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
15744             return true;
15745         }
15746
15747         // Allow storage manager to silently uninstall.
15748         if (mStorageManagerPackage != null &&
15749                 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
15750             return true;
15751         }
15752         return false;
15753     }
15754
15755     private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
15756         int[] result = EMPTY_INT_ARRAY;
15757         for (int userId : userIds) {
15758             if (getBlockUninstallForUser(packageName, userId)) {
15759                 result = ArrayUtils.appendInt(result, userId);
15760             }
15761         }
15762         return result;
15763     }
15764
15765     @Override
15766     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
15767         final int callingUid = Binder.getCallingUid();
15768         if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
15769                 != PERMISSION_GRANTED) {
15770             EventLog.writeEvent(0x534e4554, "128599183", -1, "");
15771             throw new SecurityException(android.Manifest.permission.MANAGE_USERS
15772                     + " permission is required to call this API");
15773         }
15774         return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
15775     }
15776
15777     private boolean isPackageDeviceAdmin(String packageName, int userId) {
15778         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
15779                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
15780         try {
15781             if (dpm != null) {
15782                 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
15783                         /* callingUserOnly =*/ false);
15784                 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
15785                         : deviceOwnerComponentName.getPackageName();
15786                 // Does the package contains the device owner?
15787                 // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
15788                 // this check is probably not needed, since DO should be registered as a device
15789                 // admin on some user too. (Original bug for this: b/17657954)
15790                 if (packageName.equals(deviceOwnerPackageName)) {
15791                     return true;
15792                 }
15793                 // Does it contain a device admin for any user?
15794                 int[] users;
15795                 if (userId == UserHandle.USER_ALL) {
15796                     users = sUserManager.getUserIds();
15797                 } else {
15798                     users = new int[]{userId};
15799                 }
15800                 for (int i = 0; i < users.length; ++i) {
15801                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
15802                         return true;
15803                     }
15804                 }
15805             }
15806         } catch (RemoteException e) {
15807         }
15808         return false;
15809     }
15810
15811     private boolean shouldKeepUninstalledPackageLPr(String packageName) {
15812         return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
15813     }
15814
15815     /**
15816      *  This method is an internal method that could be get invoked either
15817      *  to delete an installed package or to clean up a failed installation.
15818      *  After deleting an installed package, a broadcast is sent to notify any
15819      *  listeners that the package has been removed. For cleaning up a failed
15820      *  installation, the broadcast is not necessary since the package's
15821      *  installation wouldn't have sent the initial broadcast either
15822      *  The key steps in deleting a package are
15823      *  deleting the package information in internal structures like mPackages,
15824      *  deleting the packages base directories through installd
15825      *  updating mSettings to reflect current status
15826      *  persisting settings for later use
15827      *  sending a broadcast if necessary
15828      */
15829     private int deletePackageX(String packageName, int userId, int deleteFlags) {
15830         final PackageRemovedInfo info = new PackageRemovedInfo();
15831         final boolean res;
15832
15833         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
15834                 ? UserHandle.USER_ALL : userId;
15835
15836         if (isPackageDeviceAdmin(packageName, removeUser)) {
15837             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
15838             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
15839         }
15840
15841         PackageSetting uninstalledPs = null;
15842
15843         // for the uninstall-updates case and restricted profiles, remember the per-
15844         // user handle installed state
15845         int[] allUsers;
15846         synchronized (mPackages) {
15847             uninstalledPs = mSettings.mPackages.get(packageName);
15848             if (uninstalledPs == null) {
15849                 Slog.w(TAG, "Not removing non-existent package " + packageName);
15850                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15851             }
15852             allUsers = sUserManager.getUserIds();
15853             info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
15854         }
15855
15856         final int freezeUser;
15857         if (isUpdatedSystemApp(uninstalledPs)
15858                 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
15859             // We're downgrading a system app, which will apply to all users, so
15860             // freeze them all during the downgrade
15861             freezeUser = UserHandle.USER_ALL;
15862         } else {
15863             freezeUser = removeUser;
15864         }
15865
15866         synchronized (mInstallLock) {
15867             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
15868             try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
15869                     deleteFlags, "deletePackageX")) {
15870                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
15871                         deleteFlags | REMOVE_CHATTY, info, true, null);
15872             }
15873             synchronized (mPackages) {
15874                 if (res) {
15875                     mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
15876                 }
15877             }
15878         }
15879
15880         if (res) {
15881             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
15882             info.sendPackageRemovedBroadcasts(killApp);
15883             info.sendSystemPackageUpdatedBroadcasts();
15884             info.sendSystemPackageAppearedBroadcasts();
15885         }
15886         // Force a gc here.
15887         Runtime.getRuntime().gc();
15888         // Delete the resources here after sending the broadcast to let
15889         // other processes clean up before deleting resources.
15890         if (info.args != null) {
15891             synchronized (mInstallLock) {
15892                 info.args.doPostDeleteLI(true);
15893             }
15894         }
15895
15896         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15897     }
15898
15899     class PackageRemovedInfo {
15900         String removedPackage;
15901         int uid = -1;
15902         int removedAppId = -1;
15903         int[] origUsers;
15904         int[] removedUsers = null;
15905         boolean isRemovedPackageSystemUpdate = false;
15906         boolean isUpdate;
15907         boolean dataRemoved;
15908         boolean removedForAllUsers;
15909         // Clean up resources deleted packages.
15910         InstallArgs args = null;
15911         ArrayMap<String, PackageRemovedInfo> removedChildPackages;
15912         ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
15913
15914         void sendPackageRemovedBroadcasts(boolean killApp) {
15915             sendPackageRemovedBroadcastInternal(killApp);
15916             final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
15917             for (int i = 0; i < childCount; i++) {
15918                 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15919                 childInfo.sendPackageRemovedBroadcastInternal(killApp);
15920             }
15921         }
15922
15923         void sendSystemPackageUpdatedBroadcasts() {
15924             if (isRemovedPackageSystemUpdate) {
15925                 sendSystemPackageUpdatedBroadcastsInternal();
15926                 final int childCount = (removedChildPackages != null)
15927                         ? removedChildPackages.size() : 0;
15928                 for (int i = 0; i < childCount; i++) {
15929                     PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15930                     if (childInfo.isRemovedPackageSystemUpdate) {
15931                         childInfo.sendSystemPackageUpdatedBroadcastsInternal();
15932                     }
15933                 }
15934             }
15935         }
15936
15937         void sendSystemPackageAppearedBroadcasts() {
15938             final int packageCount = (appearedChildPackages != null)
15939                     ? appearedChildPackages.size() : 0;
15940             for (int i = 0; i < packageCount; i++) {
15941                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
15942                 for (int userId : installedInfo.newUsers) {
15943                     sendPackageAddedForUser(installedInfo.name, true,
15944                             UserHandle.getAppId(installedInfo.uid), userId);
15945                 }
15946             }
15947         }
15948
15949         private void sendSystemPackageUpdatedBroadcastsInternal() {
15950             Bundle extras = new Bundle(2);
15951             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
15952             extras.putBoolean(Intent.EXTRA_REPLACING, true);
15953             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
15954                     extras, 0, null, null, null);
15955             sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
15956                     extras, 0, null, null, null);
15957             sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
15958                     null, 0, removedPackage, null, null);
15959         }
15960
15961         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
15962             Bundle extras = new Bundle(2);
15963             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
15964             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
15965             extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
15966             if (isUpdate || isRemovedPackageSystemUpdate) {
15967                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
15968             }
15969             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
15970             if (removedPackage != null) {
15971                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
15972                         extras, 0, null, null, removedUsers);
15973                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
15974                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
15975                             removedPackage, extras, 0, null, null, removedUsers);
15976                 }
15977             }
15978             if (removedAppId >= 0) {
15979                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
15980                         removedUsers);
15981             }
15982         }
15983     }
15984
15985     /*
15986      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
15987      * flag is not set, the data directory is removed as well.
15988      * make sure this flag is set for partially installed apps. If not its meaningless to
15989      * delete a partially installed application.
15990      */
15991     private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
15992             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
15993         String packageName = ps.name;
15994         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
15995         // Retrieve object to delete permissions for shared user later on
15996         final PackageParser.Package deletedPkg;
15997         final PackageSetting deletedPs;
15998         // reader
15999         synchronized (mPackages) {
16000             deletedPkg = mPackages.get(packageName);
16001             deletedPs = mSettings.mPackages.get(packageName);
16002             if (outInfo != null) {
16003                 outInfo.removedPackage = packageName;
16004                 outInfo.removedUsers = deletedPs != null
16005                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
16006                         : null;
16007             }
16008         }
16009
16010         removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
16011
16012         if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
16013             final PackageParser.Package resolvedPkg;
16014             if (deletedPkg != null) {
16015                 resolvedPkg = deletedPkg;
16016             } else {
16017                 // We don't have a parsed package when it lives on an ejected
16018                 // adopted storage device, so fake something together
16019                 resolvedPkg = new PackageParser.Package(ps.name);
16020                 resolvedPkg.setVolumeUuid(ps.volumeUuid);
16021             }
16022             destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
16023                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16024             destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
16025             if (outInfo != null) {
16026                 outInfo.dataRemoved = true;
16027             }
16028             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
16029         }
16030
16031         // writer
16032         synchronized (mPackages) {
16033             if (deletedPs != null) {
16034                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
16035                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
16036                     clearDefaultBrowserIfNeeded(packageName);
16037                     if (outInfo != null) {
16038                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
16039                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
16040                     }
16041                     updatePermissionsLPw(deletedPs.name, null, 0);
16042                     if (deletedPs.sharedUser != null) {
16043                         // Remove permissions associated with package. Since runtime
16044                         // permissions are per user we have to kill the removed package
16045                         // or packages running under the shared user of the removed
16046                         // package if revoking the permissions requested only by the removed
16047                         // package is successful and this causes a change in gids.
16048                         for (int userId : UserManagerService.getInstance().getUserIds()) {
16049                             final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
16050                                     userId);
16051                             if (userIdToKill == UserHandle.USER_ALL
16052                                     || userIdToKill >= UserHandle.USER_SYSTEM) {
16053                                 // If gids changed for this user, kill all affected packages.
16054                                 mHandler.post(new Runnable() {
16055                                     @Override
16056                                     public void run() {
16057                                         // This has to happen with no lock held.
16058                                         killApplication(deletedPs.name, deletedPs.appId,
16059                                                 KILL_APP_REASON_GIDS_CHANGED);
16060                                     }
16061                                 });
16062                                 break;
16063                             }
16064                         }
16065                     }
16066                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
16067                 }
16068                 // make sure to preserve per-user disabled state if this removal was just
16069                 // a downgrade of a system app to the factory package
16070                 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
16071                     if (DEBUG_REMOVE) {
16072                         Slog.d(TAG, "Propagating install state across downgrade");
16073                     }
16074                     for (int userId : allUserHandles) {
16075                         final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
16076                         if (DEBUG_REMOVE) {
16077                             Slog.d(TAG, "    user " + userId + " => " + installed);
16078                         }
16079                         ps.setInstalled(installed, userId);
16080                     }
16081                 }
16082             }
16083             // can downgrade to reader
16084             if (writeSettings) {
16085                 // Save settings now
16086                 mSettings.writeLPr();
16087             }
16088         }
16089         if (outInfo != null) {
16090             // A user ID was deleted here. Go through all users and remove it
16091             // from KeyStore.
16092             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
16093         }
16094     }
16095
16096     static boolean locationIsPrivileged(File path) {
16097         try {
16098             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
16099                     .getCanonicalPath();
16100             return path.getCanonicalPath().startsWith(privilegedAppDir);
16101         } catch (IOException e) {
16102             Slog.e(TAG, "Unable to access code path " + path);
16103         }
16104         return false;
16105     }
16106
16107     /*
16108      * Tries to delete system package.
16109      */
16110     private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
16111             PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
16112             boolean writeSettings) {
16113         if (deletedPs.parentPackageName != null) {
16114             Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
16115             return false;
16116         }
16117
16118         final boolean applyUserRestrictions
16119                 = (allUserHandles != null) && (outInfo.origUsers != null);
16120         final PackageSetting disabledPs;
16121         // Confirm if the system package has been updated
16122         // An updated system app can be deleted. This will also have to restore
16123         // the system pkg from system partition
16124         // reader
16125         synchronized (mPackages) {
16126             disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
16127         }
16128
16129         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
16130                 + " disabledPs=" + disabledPs);
16131
16132         if (disabledPs == null) {
16133             Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
16134             return false;
16135         } else if (DEBUG_REMOVE) {
16136             Slog.d(TAG, "Deleting system pkg from data partition");
16137         }
16138
16139         if (DEBUG_REMOVE) {
16140             if (applyUserRestrictions) {
16141                 Slog.d(TAG, "Remembering install states:");
16142                 for (int userId : allUserHandles) {
16143                     final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
16144                     Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
16145                 }
16146             }
16147         }
16148
16149         // Delete the updated package
16150         outInfo.isRemovedPackageSystemUpdate = true;
16151         if (outInfo.removedChildPackages != null) {
16152             final int childCount = (deletedPs.childPackageNames != null)
16153                     ? deletedPs.childPackageNames.size() : 0;
16154             for (int i = 0; i < childCount; i++) {
16155                 String childPackageName = deletedPs.childPackageNames.get(i);
16156                 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
16157                         .contains(childPackageName)) {
16158                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
16159                             childPackageName);
16160                     if (childInfo != null) {
16161                         childInfo.isRemovedPackageSystemUpdate = true;
16162                     }
16163                 }
16164             }
16165         }
16166
16167         if (disabledPs.versionCode < deletedPs.versionCode) {
16168             // Delete data for downgrades
16169             flags &= ~PackageManager.DELETE_KEEP_DATA;
16170         } else {
16171             // Preserve data by setting flag
16172             flags |= PackageManager.DELETE_KEEP_DATA;
16173         }
16174
16175         boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
16176                 outInfo, writeSettings, disabledPs.pkg);
16177         if (!ret) {
16178             return false;
16179         }
16180
16181         // writer
16182         synchronized (mPackages) {
16183             // Reinstate the old system package
16184             enableSystemPackageLPw(disabledPs.pkg);
16185             // Remove any native libraries from the upgraded package.
16186             removeNativeBinariesLI(deletedPs);
16187         }
16188
16189         // Install the system package
16190         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
16191         int parseFlags = mDefParseFlags
16192                 | PackageParser.PARSE_MUST_BE_APK
16193                 | PackageParser.PARSE_IS_SYSTEM
16194                 | PackageParser.PARSE_IS_SYSTEM_DIR;
16195         if (locationIsPrivileged(disabledPs.codePath)) {
16196             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
16197         }
16198
16199         final PackageParser.Package newPkg;
16200         try {
16201             newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
16202         } catch (PackageManagerException e) {
16203             Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
16204                     + e.getMessage());
16205             return false;
16206         }
16207         try {
16208             // update shared libraries for the newly re-installed system package
16209             updateSharedLibrariesLPw(newPkg, null);
16210         } catch (PackageManagerException e) {
16211             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
16212         }
16213
16214         prepareAppDataAfterInstallLIF(newPkg);
16215
16216         // writer
16217         synchronized (mPackages) {
16218             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
16219
16220             // Propagate the permissions state as we do not want to drop on the floor
16221             // runtime permissions. The update permissions method below will take
16222             // care of removing obsolete permissions and grant install permissions.
16223             ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
16224             updatePermissionsLPw(newPkg.packageName, newPkg,
16225                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
16226
16227             if (applyUserRestrictions) {
16228                 if (DEBUG_REMOVE) {
16229                     Slog.d(TAG, "Propagating install state across reinstall");
16230                 }
16231                 for (int userId : allUserHandles) {
16232                     final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
16233                     if (DEBUG_REMOVE) {
16234                         Slog.d(TAG, "    user " + userId + " => " + installed);
16235                     }
16236                     ps.setInstalled(installed, userId);
16237
16238                     mSettings.writeRuntimePermissionsForUserLPr(userId, false);
16239                 }
16240                 // Regardless of writeSettings we need to ensure that this restriction
16241                 // state propagation is persisted
16242                 mSettings.writeAllUsersPackageRestrictionsLPr();
16243             }
16244             // can downgrade to reader here
16245             if (writeSettings) {
16246                 mSettings.writeLPr();
16247             }
16248         }
16249         return true;
16250     }
16251
16252     private boolean deleteInstalledPackageLIF(PackageSetting ps,
16253             boolean deleteCodeAndResources, int flags, int[] allUserHandles,
16254             PackageRemovedInfo outInfo, boolean writeSettings,
16255             PackageParser.Package replacingPackage) {
16256         synchronized (mPackages) {
16257             if (outInfo != null) {
16258                 outInfo.uid = ps.appId;
16259             }
16260
16261             if (outInfo != null && outInfo.removedChildPackages != null) {
16262                 final int childCount = (ps.childPackageNames != null)
16263                         ? ps.childPackageNames.size() : 0;
16264                 for (int i = 0; i < childCount; i++) {
16265                     String childPackageName = ps.childPackageNames.get(i);
16266                     PackageSetting childPs = mSettings.mPackages.get(childPackageName);
16267                     if (childPs == null) {
16268                         return false;
16269                     }
16270                     PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
16271                             childPackageName);
16272                     if (childInfo != null) {
16273                         childInfo.uid = childPs.appId;
16274                     }
16275                 }
16276             }
16277         }
16278
16279         // Delete package data from internal structures and also remove data if flag is set
16280         removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
16281
16282         // Delete the child packages data
16283         final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16284         for (int i = 0; i < childCount; i++) {
16285             PackageSetting childPs;
16286             synchronized (mPackages) {
16287                 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
16288             }
16289             if (childPs != null) {
16290                 PackageRemovedInfo childOutInfo = (outInfo != null
16291                         && outInfo.removedChildPackages != null)
16292                         ? outInfo.removedChildPackages.get(childPs.name) : null;
16293                 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
16294                         && (replacingPackage != null
16295                         && !replacingPackage.hasChildPackage(childPs.name))
16296                         ? flags & ~DELETE_KEEP_DATA : flags;
16297                 removePackageDataLIF(childPs, allUserHandles, childOutInfo,
16298                         deleteFlags, writeSettings);
16299             }
16300         }
16301
16302         // Delete application code and resources only for parent packages
16303         if (ps.parentPackageName == null) {
16304             if (deleteCodeAndResources && (outInfo != null)) {
16305                 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
16306                         ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
16307                 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
16308             }
16309         }
16310
16311         return true;
16312     }
16313
16314     @Override
16315     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
16316             int userId) {
16317         mContext.enforceCallingOrSelfPermission(
16318                 android.Manifest.permission.DELETE_PACKAGES, null);
16319         synchronized (mPackages) {
16320             PackageSetting ps = mSettings.mPackages.get(packageName);
16321             if (ps == null) {
16322                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
16323                 return false;
16324             }
16325             if (!ps.getInstalled(userId)) {
16326                 // Can't block uninstall for an app that is not installed or enabled.
16327                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
16328                 return false;
16329             }
16330             ps.setBlockUninstall(blockUninstall, userId);
16331             mSettings.writePackageRestrictionsLPr(userId);
16332         }
16333         return true;
16334     }
16335
16336     @Override
16337     public boolean getBlockUninstallForUser(String packageName, int userId) {
16338         synchronized (mPackages) {
16339             PackageSetting ps = mSettings.mPackages.get(packageName);
16340             if (ps == null) {
16341                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
16342                 return false;
16343             }
16344             return ps.getBlockUninstall(userId);
16345         }
16346     }
16347
16348     @Override
16349     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
16350         int callingUid = Binder.getCallingUid();
16351         if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
16352             throw new SecurityException(
16353                     "setRequiredForSystemUser can only be run by the system or root");
16354         }
16355         synchronized (mPackages) {
16356             PackageSetting ps = mSettings.mPackages.get(packageName);
16357             if (ps == null) {
16358                 Log.w(TAG, "Package doesn't exist: " + packageName);
16359                 return false;
16360             }
16361             if (systemUserApp) {
16362                 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
16363             } else {
16364                 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
16365             }
16366             mSettings.writeLPr();
16367         }
16368         return true;
16369     }
16370
16371     /*
16372      * This method handles package deletion in general
16373      */
16374     private boolean deletePackageLIF(String packageName, UserHandle user,
16375             boolean deleteCodeAndResources, int[] allUserHandles, int flags,
16376             PackageRemovedInfo outInfo, boolean writeSettings,
16377             PackageParser.Package replacingPackage) {
16378         if (packageName == null) {
16379             Slog.w(TAG, "Attempt to delete null packageName.");
16380             return false;
16381         }
16382
16383         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
16384
16385         PackageSetting ps;
16386
16387         synchronized (mPackages) {
16388             ps = mSettings.mPackages.get(packageName);
16389             if (ps == null) {
16390                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16391                 return false;
16392             }
16393
16394             if (ps.parentPackageName != null && (!isSystemApp(ps)
16395                     || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
16396                 if (DEBUG_REMOVE) {
16397                     Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
16398                             + ((user == null) ? UserHandle.USER_ALL : user));
16399                 }
16400                 final int removedUserId = (user != null) ? user.getIdentifier()
16401                         : UserHandle.USER_ALL;
16402                 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
16403                     return false;
16404                 }
16405                 markPackageUninstalledForUserLPw(ps, user);
16406                 scheduleWritePackageRestrictionsLocked(user);
16407                 return true;
16408             }
16409         }
16410
16411         if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
16412                 && user.getIdentifier() != UserHandle.USER_ALL)) {
16413             // The caller is asking that the package only be deleted for a single
16414             // user.  To do this, we just mark its uninstalled state and delete
16415             // its data. If this is a system app, we only allow this to happen if
16416             // they have set the special DELETE_SYSTEM_APP which requests different
16417             // semantics than normal for uninstalling system apps.
16418             markPackageUninstalledForUserLPw(ps, user);
16419
16420             if (!isSystemApp(ps)) {
16421                 // Do not uninstall the APK if an app should be cached
16422                 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
16423                 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
16424                     // Other user still have this package installed, so all
16425                     // we need to do is clear this user's data and save that
16426                     // it is uninstalled.
16427                     if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
16428                     if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16429                         return false;
16430                     }
16431                     scheduleWritePackageRestrictionsLocked(user);
16432                     return true;
16433                 } else {
16434                     // We need to set it back to 'installed' so the uninstall
16435                     // broadcasts will be sent correctly.
16436                     if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
16437                     ps.setInstalled(true, user.getIdentifier());
16438                 }
16439             } else {
16440                 // This is a system app, so we assume that the
16441                 // other users still have this package installed, so all
16442                 // we need to do is clear this user's data and save that
16443                 // it is uninstalled.
16444                 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
16445                 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16446                     return false;
16447                 }
16448                 scheduleWritePackageRestrictionsLocked(user);
16449                 return true;
16450             }
16451         }
16452
16453         // If we are deleting a composite package for all users, keep track
16454         // of result for each child.
16455         if (ps.childPackageNames != null && outInfo != null) {
16456             synchronized (mPackages) {
16457                 final int childCount = ps.childPackageNames.size();
16458                 outInfo.removedChildPackages = new ArrayMap<>(childCount);
16459                 for (int i = 0; i < childCount; i++) {
16460                     String childPackageName = ps.childPackageNames.get(i);
16461                     PackageRemovedInfo childInfo = new PackageRemovedInfo();
16462                     childInfo.removedPackage = childPackageName;
16463                     outInfo.removedChildPackages.put(childPackageName, childInfo);
16464                     PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16465                     if (childPs != null) {
16466                         childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
16467                     }
16468                 }
16469             }
16470         }
16471
16472         boolean ret = false;
16473         if (isSystemApp(ps)) {
16474             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
16475             // When an updated system application is deleted we delete the existing resources
16476             // as well and fall back to existing code in system partition
16477             ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
16478         } else {
16479             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
16480             ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
16481                     outInfo, writeSettings, replacingPackage);
16482         }
16483
16484         // Take a note whether we deleted the package for all users
16485         if (outInfo != null) {
16486             outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16487             if (outInfo.removedChildPackages != null) {
16488                 synchronized (mPackages) {
16489                     final int childCount = outInfo.removedChildPackages.size();
16490                     for (int i = 0; i < childCount; i++) {
16491                         PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
16492                         if (childInfo != null) {
16493                             childInfo.removedForAllUsers = mPackages.get(
16494                                     childInfo.removedPackage) == null;
16495                         }
16496                     }
16497                 }
16498             }
16499             // If we uninstalled an update to a system app there may be some
16500             // child packages that appeared as they are declared in the system
16501             // app but were not declared in the update.
16502             if (isSystemApp(ps)) {
16503                 synchronized (mPackages) {
16504                     PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name);
16505                     final int childCount = (updatedPs.childPackageNames != null)
16506                             ? updatedPs.childPackageNames.size() : 0;
16507                     for (int i = 0; i < childCount; i++) {
16508                         String childPackageName = updatedPs.childPackageNames.get(i);
16509                         if (outInfo.removedChildPackages == null
16510                                 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
16511                             PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16512                             if (childPs == null) {
16513                                 continue;
16514                             }
16515                             PackageInstalledInfo installRes = new PackageInstalledInfo();
16516                             installRes.name = childPackageName;
16517                             installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
16518                             installRes.pkg = mPackages.get(childPackageName);
16519                             installRes.uid = childPs.pkg.applicationInfo.uid;
16520                             if (outInfo.appearedChildPackages == null) {
16521                                 outInfo.appearedChildPackages = new ArrayMap<>();
16522                             }
16523                             outInfo.appearedChildPackages.put(childPackageName, installRes);
16524                         }
16525                     }
16526                 }
16527             }
16528         }
16529
16530         return ret;
16531     }
16532
16533     private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
16534         final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
16535                 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
16536         for (int nextUserId : userIds) {
16537             if (DEBUG_REMOVE) {
16538                 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
16539             }
16540             ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
16541                     false /*installed*/, true /*stopped*/, true /*notLaunched*/,
16542                     false /*hidden*/, false /*suspended*/, null, null, null,
16543                     false /*blockUninstall*/,
16544                     ps.readUserState(nextUserId).domainVerificationStatus, 0);
16545         }
16546     }
16547
16548     private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
16549             PackageRemovedInfo outInfo) {
16550         final PackageParser.Package pkg;
16551         synchronized (mPackages) {
16552             pkg = mPackages.get(ps.name);
16553         }
16554
16555         final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
16556                 : new int[] {userId};
16557         for (int nextUserId : userIds) {
16558             if (DEBUG_REMOVE) {
16559                 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
16560                         + nextUserId);
16561             }
16562
16563             destroyAppDataLIF(pkg, userId,
16564                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16565             destroyAppProfilesLIF(pkg, userId);
16566             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
16567             schedulePackageCleaning(ps.name, nextUserId, false);
16568             synchronized (mPackages) {
16569                 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
16570                     scheduleWritePackageRestrictionsLocked(nextUserId);
16571                 }
16572                 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
16573             }
16574         }
16575
16576         if (outInfo != null) {
16577             outInfo.removedPackage = ps.name;
16578             outInfo.removedAppId = ps.appId;
16579             outInfo.removedUsers = userIds;
16580         }
16581
16582         return true;
16583     }
16584
16585     private final class ClearStorageConnection implements ServiceConnection {
16586         IMediaContainerService mContainerService;
16587
16588         @Override
16589         public void onServiceConnected(ComponentName name, IBinder service) {
16590             synchronized (this) {
16591                 mContainerService = IMediaContainerService.Stub.asInterface(service);
16592                 notifyAll();
16593             }
16594         }
16595
16596         @Override
16597         public void onServiceDisconnected(ComponentName name) {
16598         }
16599     }
16600
16601     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
16602         if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
16603
16604         final boolean mounted;
16605         if (Environment.isExternalStorageEmulated()) {
16606             mounted = true;
16607         } else {
16608             final String status = Environment.getExternalStorageState();
16609
16610             mounted = status.equals(Environment.MEDIA_MOUNTED)
16611                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
16612         }
16613
16614         if (!mounted) {
16615             return;
16616         }
16617
16618         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
16619         int[] users;
16620         if (userId == UserHandle.USER_ALL) {
16621             users = sUserManager.getUserIds();
16622         } else {
16623             users = new int[] { userId };
16624         }
16625         final ClearStorageConnection conn = new ClearStorageConnection();
16626         if (mContext.bindServiceAsUser(
16627                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
16628             try {
16629                 for (int curUser : users) {
16630                     long timeout = SystemClock.uptimeMillis() + 5000;
16631                     synchronized (conn) {
16632                         long now;
16633                         while (conn.mContainerService == null &&
16634                                 (now = SystemClock.uptimeMillis()) < timeout) {
16635                             try {
16636                                 conn.wait(timeout - now);
16637                             } catch (InterruptedException e) {
16638                             }
16639                         }
16640                     }
16641                     if (conn.mContainerService == null) {
16642                         return;
16643                     }
16644
16645                     final UserEnvironment userEnv = new UserEnvironment(curUser);
16646                     clearDirectory(conn.mContainerService,
16647                             userEnv.buildExternalStorageAppCacheDirs(packageName));
16648                     if (allData) {
16649                         clearDirectory(conn.mContainerService,
16650                                 userEnv.buildExternalStorageAppDataDirs(packageName));
16651                         clearDirectory(conn.mContainerService,
16652                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
16653                     }
16654                 }
16655             } finally {
16656                 mContext.unbindService(conn);
16657             }
16658         }
16659     }
16660
16661     @Override
16662     public void clearApplicationProfileData(String packageName) {
16663         enforceSystemOrRoot("Only the system can clear all profile data");
16664
16665         final PackageParser.Package pkg;
16666         synchronized (mPackages) {
16667             pkg = mPackages.get(packageName);
16668         }
16669
16670         try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
16671             synchronized (mInstallLock) {
16672                 clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
16673                 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL,
16674                         true /* removeBaseMarker */);
16675             }
16676         }
16677     }
16678
16679     @Override
16680     public void clearApplicationUserData(final String packageName,
16681             final IPackageDataObserver observer, final int userId) {
16682         mContext.enforceCallingOrSelfPermission(
16683                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
16684
16685         enforceCrossUserPermission(Binder.getCallingUid(), userId,
16686                 true /* requireFullPermission */, false /* checkShell */, "clear application data");
16687
16688         if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
16689             throw new SecurityException("Cannot clear data for a protected package: "
16690                     + packageName);
16691         }
16692         // Queue up an async operation since the package deletion may take a little while.
16693         mHandler.post(new Runnable() {
16694             public void run() {
16695                 mHandler.removeCallbacks(this);
16696                 final boolean succeeded;
16697                 try (PackageFreezer freezer = freezePackage(packageName,
16698                         "clearApplicationUserData")) {
16699                     synchronized (mInstallLock) {
16700                         succeeded = clearApplicationUserDataLIF(packageName, userId);
16701                     }
16702                     clearExternalStorageDataSync(packageName, userId, true);
16703                 }
16704                 if (succeeded) {
16705                     // invoke DeviceStorageMonitor's update method to clear any notifications
16706                     DeviceStorageMonitorInternal dsm = LocalServices
16707                             .getService(DeviceStorageMonitorInternal.class);
16708                     if (dsm != null) {
16709                         dsm.checkMemory();
16710                     }
16711                 }
16712                 if(observer != null) {
16713                     try {
16714                         observer.onRemoveCompleted(packageName, succeeded);
16715                     } catch (RemoteException e) {
16716                         Log.i(TAG, "Observer no longer exists.");
16717                     }
16718                 } //end if observer
16719             } //end run
16720         });
16721     }
16722
16723     private boolean clearApplicationUserDataLIF(String packageName, int userId) {
16724         if (packageName == null) {
16725             Slog.w(TAG, "Attempt to delete null packageName.");
16726             return false;
16727         }
16728
16729         // Try finding details about the requested package
16730         PackageParser.Package pkg;
16731         synchronized (mPackages) {
16732             pkg = mPackages.get(packageName);
16733             if (pkg == null) {
16734                 final PackageSetting ps = mSettings.mPackages.get(packageName);
16735                 if (ps != null) {
16736                     pkg = ps.pkg;
16737                 }
16738             }
16739
16740             if (pkg == null) {
16741                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16742                 return false;
16743             }
16744
16745             PackageSetting ps = (PackageSetting) pkg.mExtras;
16746             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16747         }
16748
16749         clearAppDataLIF(pkg, userId,
16750                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16751
16752         final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16753         removeKeystoreDataIfNeeded(userId, appId);
16754
16755         UserManagerInternal umInternal = getUserManagerInternal();
16756         final int flags;
16757         if (umInternal.isUserUnlockingOrUnlocked(userId)) {
16758             flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
16759         } else if (umInternal.isUserRunning(userId)) {
16760             flags = StorageManager.FLAG_STORAGE_DE;
16761         } else {
16762             flags = 0;
16763         }
16764         prepareAppDataContentsLIF(pkg, userId, flags);
16765
16766         return true;
16767     }
16768
16769     /**
16770      * Reverts user permission state changes (permissions and flags) in
16771      * all packages for a given user.
16772      *
16773      * @param userId The device user for which to do a reset.
16774      */
16775     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
16776         final int packageCount = mPackages.size();
16777         for (int i = 0; i < packageCount; i++) {
16778             PackageParser.Package pkg = mPackages.valueAt(i);
16779             PackageSetting ps = (PackageSetting) pkg.mExtras;
16780             resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16781         }
16782     }
16783
16784     private void resetNetworkPolicies(int userId) {
16785         LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
16786     }
16787
16788     /**
16789      * Reverts user permission state changes (permissions and flags).
16790      *
16791      * @param ps The package for which to reset.
16792      * @param userId The device user for which to do a reset.
16793      */
16794     private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
16795             final PackageSetting ps, final int userId) {
16796         if (ps.pkg == null) {
16797             return;
16798         }
16799
16800         // These are flags that can change base on user actions.
16801         final int userSettableMask = FLAG_PERMISSION_USER_SET
16802                 | FLAG_PERMISSION_USER_FIXED
16803                 | FLAG_PERMISSION_REVOKE_ON_UPGRADE
16804                 | FLAG_PERMISSION_REVIEW_REQUIRED;
16805
16806         final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
16807                 | FLAG_PERMISSION_POLICY_FIXED;
16808
16809         boolean writeInstallPermissions = false;
16810         boolean writeRuntimePermissions = false;
16811
16812         final int permissionCount = ps.pkg.requestedPermissions.size();
16813         for (int i = 0; i < permissionCount; i++) {
16814             String permission = ps.pkg.requestedPermissions.get(i);
16815
16816             BasePermission bp = mSettings.mPermissions.get(permission);
16817             if (bp == null) {
16818                 continue;
16819             }
16820
16821             // If shared user we just reset the state to which only this app contributed.
16822             if (ps.sharedUser != null) {
16823                 boolean used = false;
16824                 final int packageCount = ps.sharedUser.packages.size();
16825                 for (int j = 0; j < packageCount; j++) {
16826                     PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
16827                     if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
16828                             && pkg.pkg.requestedPermissions.contains(permission)) {
16829                         used = true;
16830                         break;
16831                     }
16832                 }
16833                 if (used) {
16834                     continue;
16835                 }
16836             }
16837
16838             PermissionsState permissionsState = ps.getPermissionsState();
16839
16840             final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
16841
16842             // Always clear the user settable flags.
16843             final boolean hasInstallState = permissionsState.getInstallPermissionState(
16844                     bp.name) != null;
16845             // If permission review is enabled and this is a legacy app, mark the
16846             // permission as requiring a review as this is the initial state.
16847             int flags = 0;
16848             if (Build.PERMISSIONS_REVIEW_REQUIRED
16849                     && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
16850                 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
16851             }
16852             if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
16853                 if (hasInstallState) {
16854                     writeInstallPermissions = true;
16855                 } else {
16856                     writeRuntimePermissions = true;
16857                 }
16858             }
16859
16860             // Below is only runtime permission handling.
16861             if (!bp.isRuntime()) {
16862                 continue;
16863             }
16864
16865             // Never clobber system or policy.
16866             if ((oldFlags & policyOrSystemFlags) != 0) {
16867                 continue;
16868             }
16869
16870             // If this permission was granted by default, make sure it is.
16871             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
16872                 if (permissionsState.grantRuntimePermission(bp, userId)
16873                         != PERMISSION_OPERATION_FAILURE) {
16874                     writeRuntimePermissions = true;
16875                 }
16876             // If permission review is enabled the permissions for a legacy apps
16877             // are represented as constantly granted runtime ones, so don't revoke.
16878             } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
16879                 // Otherwise, reset the permission.
16880                 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
16881                 switch (revokeResult) {
16882                     case PERMISSION_OPERATION_SUCCESS:
16883                     case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
16884                         writeRuntimePermissions = true;
16885                         final int appId = ps.appId;
16886                         mHandler.post(new Runnable() {
16887                             @Override
16888                             public void run() {
16889                                 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
16890                             }
16891                         });
16892                     } break;
16893                 }
16894             }
16895         }
16896
16897         // Synchronously write as we are taking permissions away.
16898         if (writeRuntimePermissions) {
16899             mSettings.writeRuntimePermissionsForUserLPr(userId, true);
16900         }
16901
16902         // Synchronously write as we are taking permissions away.
16903         if (writeInstallPermissions) {
16904             mSettings.writeLPr();
16905         }
16906     }
16907
16908     /**
16909      * Remove entries from the keystore daemon. Will only remove it if the
16910      * {@code appId} is valid.
16911      */
16912     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
16913         if (appId < 0) {
16914             return;
16915         }
16916
16917         final KeyStore keyStore = KeyStore.getInstance();
16918         if (keyStore != null) {
16919             if (userId == UserHandle.USER_ALL) {
16920                 for (final int individual : sUserManager.getUserIds()) {
16921                     keyStore.clearUid(UserHandle.getUid(individual, appId));
16922                 }
16923             } else {
16924                 keyStore.clearUid(UserHandle.getUid(userId, appId));
16925             }
16926         } else {
16927             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
16928         }
16929     }
16930
16931     @Override
16932     public void deleteApplicationCacheFiles(final String packageName,
16933             final IPackageDataObserver observer) {
16934         final int userId = UserHandle.getCallingUserId();
16935         deleteApplicationCacheFilesAsUser(packageName, userId, observer);
16936     }
16937
16938     @Override
16939     public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
16940             final IPackageDataObserver observer) {
16941         mContext.enforceCallingOrSelfPermission(
16942                 android.Manifest.permission.DELETE_CACHE_FILES, null);
16943         enforceCrossUserPermission(Binder.getCallingUid(), userId,
16944                 /* requireFullPermission= */ true, /* checkShell= */ false,
16945                 "delete application cache files");
16946
16947         final PackageParser.Package pkg;
16948         synchronized (mPackages) {
16949             pkg = mPackages.get(packageName);
16950         }
16951
16952         // Queue up an async operation since the package deletion may take a little while.
16953         mHandler.post(new Runnable() {
16954             public void run() {
16955                 synchronized (mInstallLock) {
16956                     final int flags = StorageManager.FLAG_STORAGE_DE
16957                             | StorageManager.FLAG_STORAGE_CE;
16958                     // We're only clearing cache files, so we don't care if the
16959                     // app is unfrozen and still able to run
16960                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
16961                     clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16962                 }
16963                 clearExternalStorageDataSync(packageName, userId, false);
16964                 if (observer != null) {
16965                     try {
16966                         observer.onRemoveCompleted(packageName, true);
16967                     } catch (RemoteException e) {
16968                         Log.i(TAG, "Observer no longer exists.");
16969                     }
16970                 }
16971             }
16972         });
16973     }
16974
16975     @Override
16976     public void getPackageSizeInfo(final String packageName, int userHandle,
16977             final IPackageStatsObserver observer) {
16978         mContext.enforceCallingOrSelfPermission(
16979                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
16980         if (packageName == null) {
16981             throw new IllegalArgumentException("Attempt to get size of null packageName");
16982         }
16983
16984         PackageStats stats = new PackageStats(packageName, userHandle);
16985
16986         /*
16987          * Queue up an async operation since the package measurement may take a
16988          * little while.
16989          */
16990         Message msg = mHandler.obtainMessage(INIT_COPY);
16991         msg.obj = new MeasureParams(stats, observer);
16992         mHandler.sendMessage(msg);
16993     }
16994
16995     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
16996         final PackageSetting ps;
16997         synchronized (mPackages) {
16998             ps = mSettings.mPackages.get(packageName);
16999             if (ps == null) {
17000                 Slog.w(TAG, "Failed to find settings for " + packageName);
17001                 return false;
17002             }
17003         }
17004         try {
17005             mInstaller.getAppSize(ps.volumeUuid, packageName, userId,
17006                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE,
17007                     ps.getCeDataInode(userId), ps.codePathString, stats);
17008         } catch (InstallerException e) {
17009             Slog.w(TAG, String.valueOf(e));
17010             return false;
17011         }
17012
17013         // For now, ignore code size of packages on system partition
17014         if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
17015             stats.codeSize = 0;
17016         }
17017
17018         return true;
17019     }
17020
17021     private int getUidTargetSdkVersionLockedLPr(int uid) {
17022         Object obj = mSettings.getUserIdLPr(uid);
17023         if (obj instanceof SharedUserSetting) {
17024             final SharedUserSetting sus = (SharedUserSetting) obj;
17025             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
17026             final Iterator<PackageSetting> it = sus.packages.iterator();
17027             while (it.hasNext()) {
17028                 final PackageSetting ps = it.next();
17029                 if (ps.pkg != null) {
17030                     int v = ps.pkg.applicationInfo.targetSdkVersion;
17031                     if (v < vers) vers = v;
17032                 }
17033             }
17034             return vers;
17035         } else if (obj instanceof PackageSetting) {
17036             final PackageSetting ps = (PackageSetting) obj;
17037             if (ps.pkg != null) {
17038                 return ps.pkg.applicationInfo.targetSdkVersion;
17039             }
17040         }
17041         return Build.VERSION_CODES.CUR_DEVELOPMENT;
17042     }
17043
17044     @Override
17045     public void addPreferredActivity(IntentFilter filter, int match,
17046             ComponentName[] set, ComponentName activity, int userId) {
17047         addPreferredActivityInternal(filter, match, set, activity, true, userId,
17048                 "Adding preferred");
17049     }
17050
17051     private void addPreferredActivityInternal(IntentFilter filter, int match,
17052             ComponentName[] set, ComponentName activity, boolean always, int userId,
17053             String opname) {
17054         // writer
17055         int callingUid = Binder.getCallingUid();
17056         enforceCrossUserPermission(callingUid, userId,
17057                 true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
17058         if (filter.countActions() == 0) {
17059             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
17060             return;
17061         }
17062         synchronized (mPackages) {
17063             if (mContext.checkCallingOrSelfPermission(
17064                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17065                     != PackageManager.PERMISSION_GRANTED) {
17066                 if (getUidTargetSdkVersionLockedLPr(callingUid)
17067                         < Build.VERSION_CODES.FROYO) {
17068                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
17069                             + callingUid);
17070                     return;
17071                 }
17072                 mContext.enforceCallingOrSelfPermission(
17073                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17074             }
17075
17076             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
17077             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
17078                     + userId + ":");
17079             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17080             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
17081             scheduleWritePackageRestrictionsLocked(userId);
17082             postPreferredActivityChangedBroadcast(userId);
17083         }
17084     }
17085
17086     private void postPreferredActivityChangedBroadcast(int userId) {
17087         mHandler.post(() -> {
17088             final IActivityManager am = ActivityManagerNative.getDefault();
17089             if (am == null) {
17090                 return;
17091             }
17092
17093             final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
17094             intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17095             try {
17096                 am.broadcastIntent(null, intent, null, null,
17097                         0, null, null, null, android.app.AppOpsManager.OP_NONE,
17098                         null, false, false, userId);
17099             } catch (RemoteException e) {
17100             }
17101         });
17102     }
17103
17104     @Override
17105     public void replacePreferredActivity(IntentFilter filter, int match,
17106             ComponentName[] set, ComponentName activity, int userId) {
17107         if (filter.countActions() != 1) {
17108             throw new IllegalArgumentException(
17109                     "replacePreferredActivity expects filter to have only 1 action.");
17110         }
17111         if (filter.countDataAuthorities() != 0
17112                 || filter.countDataPaths() != 0
17113                 || filter.countDataSchemes() > 1
17114                 || filter.countDataTypes() != 0) {
17115             throw new IllegalArgumentException(
17116                     "replacePreferredActivity expects filter to have no data authorities, " +
17117                     "paths, or types; and at most one scheme.");
17118         }
17119
17120         final int callingUid = Binder.getCallingUid();
17121         enforceCrossUserPermission(callingUid, userId,
17122                 true /* requireFullPermission */, false /* checkShell */,
17123                 "replace preferred activity");
17124         synchronized (mPackages) {
17125             if (mContext.checkCallingOrSelfPermission(
17126                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17127                     != PackageManager.PERMISSION_GRANTED) {
17128                 if (getUidTargetSdkVersionLockedLPr(callingUid)
17129                         < Build.VERSION_CODES.FROYO) {
17130                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
17131                             + Binder.getCallingUid());
17132                     return;
17133                 }
17134                 mContext.enforceCallingOrSelfPermission(
17135                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17136             }
17137
17138             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
17139             if (pir != null) {
17140                 // Get all of the existing entries that exactly match this filter.
17141                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
17142                 if (existing != null && existing.size() == 1) {
17143                     PreferredActivity cur = existing.get(0);
17144                     if (DEBUG_PREFERRED) {
17145                         Slog.i(TAG, "Checking replace of preferred:");
17146                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17147                         if (!cur.mPref.mAlways) {
17148                             Slog.i(TAG, "  -- CUR; not mAlways!");
17149                         } else {
17150                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
17151                             Slog.i(TAG, "  -- CUR: mSet="
17152                                     + Arrays.toString(cur.mPref.mSetComponents));
17153                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
17154                             Slog.i(TAG, "  -- NEW: mMatch="
17155                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
17156                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
17157                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
17158                         }
17159                     }
17160                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
17161                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
17162                             && cur.mPref.sameSet(set)) {
17163                         // Setting the preferred activity to what it happens to be already
17164                         if (DEBUG_PREFERRED) {
17165                             Slog.i(TAG, "Replacing with same preferred activity "
17166                                     + cur.mPref.mShortComponent + " for user "
17167                                     + userId + ":");
17168                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17169                         }
17170                         return;
17171                     }
17172                 }
17173
17174                 if (existing != null) {
17175                     if (DEBUG_PREFERRED) {
17176                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
17177                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17178                     }
17179                     for (int i = 0; i < existing.size(); i++) {
17180                         PreferredActivity pa = existing.get(i);
17181                         if (DEBUG_PREFERRED) {
17182                             Slog.i(TAG, "Removing existing preferred activity "
17183                                     + pa.mPref.mComponent + ":");
17184                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
17185                         }
17186                         pir.removeFilter(pa);
17187                     }
17188                 }
17189             }
17190             addPreferredActivityInternal(filter, match, set, activity, true, userId,
17191                     "Replacing preferred");
17192         }
17193     }
17194
17195     @Override
17196     public void clearPackagePreferredActivities(String packageName) {
17197         final int uid = Binder.getCallingUid();
17198         // writer
17199         synchronized (mPackages) {
17200             PackageParser.Package pkg = mPackages.get(packageName);
17201             if (pkg == null || pkg.applicationInfo.uid != uid) {
17202                 if (mContext.checkCallingOrSelfPermission(
17203                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17204                         != PackageManager.PERMISSION_GRANTED) {
17205                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
17206                             < Build.VERSION_CODES.FROYO) {
17207                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
17208                                 + Binder.getCallingUid());
17209                         return;
17210                     }
17211                     mContext.enforceCallingOrSelfPermission(
17212                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17213                 }
17214             }
17215
17216             int user = UserHandle.getCallingUserId();
17217             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
17218                 scheduleWritePackageRestrictionsLocked(user);
17219             }
17220         }
17221     }
17222
17223     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17224     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
17225         ArrayList<PreferredActivity> removed = null;
17226         boolean changed = false;
17227         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
17228             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
17229             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
17230             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
17231                 continue;
17232             }
17233             Iterator<PreferredActivity> it = pir.filterIterator();
17234             while (it.hasNext()) {
17235                 PreferredActivity pa = it.next();
17236                 // Mark entry for removal only if it matches the package name
17237                 // and the entry is of type "always".
17238                 if (packageName == null ||
17239                         (pa.mPref.mComponent.getPackageName().equals(packageName)
17240                                 && pa.mPref.mAlways)) {
17241                     if (removed == null) {
17242                         removed = new ArrayList<PreferredActivity>();
17243                     }
17244                     removed.add(pa);
17245                 }
17246             }
17247             if (removed != null) {
17248                 for (int j=0; j<removed.size(); j++) {
17249                     PreferredActivity pa = removed.get(j);
17250                     pir.removeFilter(pa);
17251                 }
17252                 changed = true;
17253             }
17254         }
17255         if (changed) {
17256             postPreferredActivityChangedBroadcast(userId);
17257         }
17258         return changed;
17259     }
17260
17261     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17262     private void clearIntentFilterVerificationsLPw(int userId) {
17263         final int packageCount = mPackages.size();
17264         for (int i = 0; i < packageCount; i++) {
17265             PackageParser.Package pkg = mPackages.valueAt(i);
17266             clearIntentFilterVerificationsLPw(pkg.packageName, userId);
17267         }
17268     }
17269
17270     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17271     void clearIntentFilterVerificationsLPw(String packageName, int userId) {
17272         if (userId == UserHandle.USER_ALL) {
17273             if (mSettings.removeIntentFilterVerificationLPw(packageName,
17274                     sUserManager.getUserIds())) {
17275                 for (int oneUserId : sUserManager.getUserIds()) {
17276                     scheduleWritePackageRestrictionsLocked(oneUserId);
17277                 }
17278             }
17279         } else {
17280             if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
17281                 scheduleWritePackageRestrictionsLocked(userId);
17282             }
17283         }
17284     }
17285
17286     void clearDefaultBrowserIfNeeded(String packageName) {
17287         for (int oneUserId : sUserManager.getUserIds()) {
17288             String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
17289             if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
17290             if (packageName.equals(defaultBrowserPackageName)) {
17291                 setDefaultBrowserPackageName(null, oneUserId);
17292             }
17293         }
17294     }
17295
17296     @Override
17297     public void resetApplicationPreferences(int userId) {
17298         mContext.enforceCallingOrSelfPermission(
17299                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17300         final long identity = Binder.clearCallingIdentity();
17301         // writer
17302         try {
17303             synchronized (mPackages) {
17304                 clearPackagePreferredActivitiesLPw(null, userId);
17305                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
17306                 // TODO: We have to reset the default SMS and Phone. This requires
17307                 // significant refactoring to keep all default apps in the package
17308                 // manager (cleaner but more work) or have the services provide
17309                 // callbacks to the package manager to request a default app reset.
17310                 applyFactoryDefaultBrowserLPw(userId);
17311                 clearIntentFilterVerificationsLPw(userId);
17312                 primeDomainVerificationsLPw(userId);
17313                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
17314                 scheduleWritePackageRestrictionsLocked(userId);
17315             }
17316             resetNetworkPolicies(userId);
17317         } finally {
17318             Binder.restoreCallingIdentity(identity);
17319         }
17320     }
17321
17322     @Override
17323     public int getPreferredActivities(List<IntentFilter> outFilters,
17324             List<ComponentName> outActivities, String packageName) {
17325
17326         int num = 0;
17327         final int userId = UserHandle.getCallingUserId();
17328         // reader
17329         synchronized (mPackages) {
17330             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
17331             if (pir != null) {
17332                 final Iterator<PreferredActivity> it = pir.filterIterator();
17333                 while (it.hasNext()) {
17334                     final PreferredActivity pa = it.next();
17335                     if (packageName == null
17336                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
17337                                     && pa.mPref.mAlways)) {
17338                         if (outFilters != null) {
17339                             outFilters.add(new IntentFilter(pa));
17340                         }
17341                         if (outActivities != null) {
17342                             outActivities.add(pa.mPref.mComponent);
17343                         }
17344                     }
17345                 }
17346             }
17347         }
17348
17349         return num;
17350     }
17351
17352     @Override
17353     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
17354             int userId) {
17355         int callingUid = Binder.getCallingUid();
17356         if (callingUid != Process.SYSTEM_UID) {
17357             throw new SecurityException(
17358                     "addPersistentPreferredActivity can only be run by the system");
17359         }
17360         if (filter.countActions() == 0) {
17361             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
17362             return;
17363         }
17364         synchronized (mPackages) {
17365             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
17366                     ":");
17367             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17368             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
17369                     new PersistentPreferredActivity(filter, activity));
17370             scheduleWritePackageRestrictionsLocked(userId);
17371             postPreferredActivityChangedBroadcast(userId);
17372         }
17373     }
17374
17375     @Override
17376     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
17377         int callingUid = Binder.getCallingUid();
17378         if (callingUid != Process.SYSTEM_UID) {
17379             throw new SecurityException(
17380                     "clearPackagePersistentPreferredActivities can only be run by the system");
17381         }
17382         ArrayList<PersistentPreferredActivity> removed = null;
17383         boolean changed = false;
17384         synchronized (mPackages) {
17385             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
17386                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
17387                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
17388                         .valueAt(i);
17389                 if (userId != thisUserId) {
17390                     continue;
17391                 }
17392                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
17393                 while (it.hasNext()) {
17394                     PersistentPreferredActivity ppa = it.next();
17395                     // Mark entry for removal only if it matches the package name.
17396                     if (ppa.mComponent.getPackageName().equals(packageName)) {
17397                         if (removed == null) {
17398                             removed = new ArrayList<PersistentPreferredActivity>();
17399                         }
17400                         removed.add(ppa);
17401                     }
17402                 }
17403                 if (removed != null) {
17404                     for (int j=0; j<removed.size(); j++) {
17405                         PersistentPreferredActivity ppa = removed.get(j);
17406                         ppir.removeFilter(ppa);
17407                     }
17408                     changed = true;
17409                 }
17410             }
17411
17412             if (changed) {
17413                 scheduleWritePackageRestrictionsLocked(userId);
17414                 postPreferredActivityChangedBroadcast(userId);
17415             }
17416         }
17417     }
17418
17419     /**
17420      * Common machinery for picking apart a restored XML blob and passing
17421      * it to a caller-supplied functor to be applied to the running system.
17422      */
17423     private void restoreFromXml(XmlPullParser parser, int userId,
17424             String expectedStartTag, BlobXmlRestorer functor)
17425             throws IOException, XmlPullParserException {
17426         int type;
17427         while ((type = parser.next()) != XmlPullParser.START_TAG
17428                 && type != XmlPullParser.END_DOCUMENT) {
17429         }
17430         if (type != XmlPullParser.START_TAG) {
17431             // oops didn't find a start tag?!
17432             if (DEBUG_BACKUP) {
17433                 Slog.e(TAG, "Didn't find start tag during restore");
17434             }
17435             return;
17436         }
17437 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
17438         // this is supposed to be TAG_PREFERRED_BACKUP
17439         if (!expectedStartTag.equals(parser.getName())) {
17440             if (DEBUG_BACKUP) {
17441                 Slog.e(TAG, "Found unexpected tag " + parser.getName());
17442             }
17443             return;
17444         }
17445
17446         // skip interfering stuff, then we're aligned with the backing implementation
17447         while ((type = parser.next()) == XmlPullParser.TEXT) { }
17448 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
17449         functor.apply(parser, userId);
17450     }
17451
17452     private interface BlobXmlRestorer {
17453         public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
17454     }
17455
17456     /**
17457      * Non-Binder method, support for the backup/restore mechanism: write the
17458      * full set of preferred activities in its canonical XML format.  Returns the
17459      * XML output as a byte array, or null if there is none.
17460      */
17461     @Override
17462     public byte[] getPreferredActivityBackup(int userId) {
17463         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17464             throw new SecurityException("Only the system may call getPreferredActivityBackup()");
17465         }
17466
17467         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17468         try {
17469             final XmlSerializer serializer = new FastXmlSerializer();
17470             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17471             serializer.startDocument(null, true);
17472             serializer.startTag(null, TAG_PREFERRED_BACKUP);
17473
17474             synchronized (mPackages) {
17475                 mSettings.writePreferredActivitiesLPr(serializer, userId, true);
17476             }
17477
17478             serializer.endTag(null, TAG_PREFERRED_BACKUP);
17479             serializer.endDocument();
17480             serializer.flush();
17481         } catch (Exception e) {
17482             if (DEBUG_BACKUP) {
17483                 Slog.e(TAG, "Unable to write preferred activities for backup", e);
17484             }
17485             return null;
17486         }
17487
17488         return dataStream.toByteArray();
17489     }
17490
17491     @Override
17492     public void restorePreferredActivities(byte[] backup, int userId) {
17493         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17494             throw new SecurityException("Only the system may call restorePreferredActivities()");
17495         }
17496
17497         try {
17498             final XmlPullParser parser = Xml.newPullParser();
17499             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17500             restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
17501                     new BlobXmlRestorer() {
17502                         @Override
17503                         public void apply(XmlPullParser parser, int userId)
17504                                 throws XmlPullParserException, IOException {
17505                             synchronized (mPackages) {
17506                                 mSettings.readPreferredActivitiesLPw(parser, userId);
17507                             }
17508                         }
17509                     } );
17510         } catch (Exception e) {
17511             if (DEBUG_BACKUP) {
17512                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17513             }
17514         }
17515     }
17516
17517     /**
17518      * Non-Binder method, support for the backup/restore mechanism: write the
17519      * default browser (etc) settings in its canonical XML format.  Returns the default
17520      * browser XML representation as a byte array, or null if there is none.
17521      */
17522     @Override
17523     public byte[] getDefaultAppsBackup(int userId) {
17524         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17525             throw new SecurityException("Only the system may call getDefaultAppsBackup()");
17526         }
17527
17528         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17529         try {
17530             final XmlSerializer serializer = new FastXmlSerializer();
17531             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17532             serializer.startDocument(null, true);
17533             serializer.startTag(null, TAG_DEFAULT_APPS);
17534
17535             synchronized (mPackages) {
17536                 mSettings.writeDefaultAppsLPr(serializer, userId);
17537             }
17538
17539             serializer.endTag(null, TAG_DEFAULT_APPS);
17540             serializer.endDocument();
17541             serializer.flush();
17542         } catch (Exception e) {
17543             if (DEBUG_BACKUP) {
17544                 Slog.e(TAG, "Unable to write default apps for backup", e);
17545             }
17546             return null;
17547         }
17548
17549         return dataStream.toByteArray();
17550     }
17551
17552     @Override
17553     public void restoreDefaultApps(byte[] backup, int userId) {
17554         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17555             throw new SecurityException("Only the system may call restoreDefaultApps()");
17556         }
17557
17558         try {
17559             final XmlPullParser parser = Xml.newPullParser();
17560             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17561             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
17562                     new BlobXmlRestorer() {
17563                         @Override
17564                         public void apply(XmlPullParser parser, int userId)
17565                                 throws XmlPullParserException, IOException {
17566                             synchronized (mPackages) {
17567                                 mSettings.readDefaultAppsLPw(parser, userId);
17568                             }
17569                         }
17570                     } );
17571         } catch (Exception e) {
17572             if (DEBUG_BACKUP) {
17573                 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
17574             }
17575         }
17576     }
17577
17578     @Override
17579     public byte[] getIntentFilterVerificationBackup(int userId) {
17580         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17581             throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
17582         }
17583
17584         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17585         try {
17586             final XmlSerializer serializer = new FastXmlSerializer();
17587             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17588             serializer.startDocument(null, true);
17589             serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
17590
17591             synchronized (mPackages) {
17592                 mSettings.writeAllDomainVerificationsLPr(serializer, userId);
17593             }
17594
17595             serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
17596             serializer.endDocument();
17597             serializer.flush();
17598         } catch (Exception e) {
17599             if (DEBUG_BACKUP) {
17600                 Slog.e(TAG, "Unable to write default apps for backup", e);
17601             }
17602             return null;
17603         }
17604
17605         return dataStream.toByteArray();
17606     }
17607
17608     @Override
17609     public void restoreIntentFilterVerification(byte[] backup, int userId) {
17610         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17611             throw new SecurityException("Only the system may call restorePreferredActivities()");
17612         }
17613
17614         try {
17615             final XmlPullParser parser = Xml.newPullParser();
17616             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17617             restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
17618                     new BlobXmlRestorer() {
17619                         @Override
17620                         public void apply(XmlPullParser parser, int userId)
17621                                 throws XmlPullParserException, IOException {
17622                             synchronized (mPackages) {
17623                                 mSettings.readAllDomainVerificationsLPr(parser, userId);
17624                                 mSettings.writeLPr();
17625                             }
17626                         }
17627                     } );
17628         } catch (Exception e) {
17629             if (DEBUG_BACKUP) {
17630                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17631             }
17632         }
17633     }
17634
17635     @Override
17636     public byte[] getPermissionGrantBackup(int userId) {
17637         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17638             throw new SecurityException("Only the system may call getPermissionGrantBackup()");
17639         }
17640
17641         ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17642         try {
17643             final XmlSerializer serializer = new FastXmlSerializer();
17644             serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17645             serializer.startDocument(null, true);
17646             serializer.startTag(null, TAG_PERMISSION_BACKUP);
17647
17648             synchronized (mPackages) {
17649                 serializeRuntimePermissionGrantsLPr(serializer, userId);
17650             }
17651
17652             serializer.endTag(null, TAG_PERMISSION_BACKUP);
17653             serializer.endDocument();
17654             serializer.flush();
17655         } catch (Exception e) {
17656             if (DEBUG_BACKUP) {
17657                 Slog.e(TAG, "Unable to write default apps for backup", e);
17658             }
17659             return null;
17660         }
17661
17662         return dataStream.toByteArray();
17663     }
17664
17665     @Override
17666     public void restorePermissionGrants(byte[] backup, int userId) {
17667         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17668             throw new SecurityException("Only the system may call restorePermissionGrants()");
17669         }
17670
17671         try {
17672             final XmlPullParser parser = Xml.newPullParser();
17673             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17674             restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
17675                     new BlobXmlRestorer() {
17676                         @Override
17677                         public void apply(XmlPullParser parser, int userId)
17678                                 throws XmlPullParserException, IOException {
17679                             synchronized (mPackages) {
17680                                 processRestoredPermissionGrantsLPr(parser, userId);
17681                             }
17682                         }
17683                     } );
17684         } catch (Exception e) {
17685             if (DEBUG_BACKUP) {
17686                 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17687             }
17688         }
17689     }
17690
17691     private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
17692             throws IOException {
17693         serializer.startTag(null, TAG_ALL_GRANTS);
17694
17695         final int N = mSettings.mPackages.size();
17696         for (int i = 0; i < N; i++) {
17697             final PackageSetting ps = mSettings.mPackages.valueAt(i);
17698             boolean pkgGrantsKnown = false;
17699
17700             PermissionsState packagePerms = ps.getPermissionsState();
17701
17702             for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
17703                 final int grantFlags = state.getFlags();
17704                 // only look at grants that are not system/policy fixed
17705                 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
17706                     final boolean isGranted = state.isGranted();
17707                     // And only back up the user-twiddled state bits
17708                     if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
17709                         final String packageName = mSettings.mPackages.keyAt(i);
17710                         if (!pkgGrantsKnown) {
17711                             serializer.startTag(null, TAG_GRANT);
17712                             serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
17713                             pkgGrantsKnown = true;
17714                         }
17715
17716                         final boolean userSet =
17717                                 (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
17718                         final boolean userFixed =
17719                                 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
17720                         final boolean revoke =
17721                                 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
17722
17723                         serializer.startTag(null, TAG_PERMISSION);
17724                         serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
17725                         if (isGranted) {
17726                             serializer.attribute(null, ATTR_IS_GRANTED, "true");
17727                         }
17728                         if (userSet) {
17729                             serializer.attribute(null, ATTR_USER_SET, "true");
17730                         }
17731                         if (userFixed) {
17732                             serializer.attribute(null, ATTR_USER_FIXED, "true");
17733                         }
17734                         if (revoke) {
17735                             serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
17736                         }
17737                         serializer.endTag(null, TAG_PERMISSION);
17738                     }
17739                 }
17740             }
17741
17742             if (pkgGrantsKnown) {
17743                 serializer.endTag(null, TAG_GRANT);
17744             }
17745         }
17746
17747         serializer.endTag(null, TAG_ALL_GRANTS);
17748     }
17749
17750     private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
17751             throws XmlPullParserException, IOException {
17752         String pkgName = null;
17753         int outerDepth = parser.getDepth();
17754         int type;
17755         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
17756                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
17757             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
17758                 continue;
17759             }
17760
17761             final String tagName = parser.getName();
17762             if (tagName.equals(TAG_GRANT)) {
17763                 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
17764                 if (DEBUG_BACKUP) {
17765                     Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
17766                 }
17767             } else if (tagName.equals(TAG_PERMISSION)) {
17768
17769                 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
17770                 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
17771
17772                 int newFlagSet = 0;
17773                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
17774                     newFlagSet |= FLAG_PERMISSION_USER_SET;
17775                 }
17776                 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
17777                     newFlagSet |= FLAG_PERMISSION_USER_FIXED;
17778                 }
17779                 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
17780                     newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
17781                 }
17782                 if (DEBUG_BACKUP) {
17783                     Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
17784                             + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
17785                 }
17786                 final PackageSetting ps = mSettings.mPackages.get(pkgName);
17787                 if (ps != null) {
17788                     // Already installed so we apply the grant immediately
17789                     if (DEBUG_BACKUP) {
17790                         Slog.v(TAG, "        + already installed; applying");
17791                     }
17792                     PermissionsState perms = ps.getPermissionsState();
17793                     BasePermission bp = mSettings.mPermissions.get(permName);
17794                     if (bp != null) {
17795                         if (isGranted) {
17796                             perms.grantRuntimePermission(bp, userId);
17797                         }
17798                         if (newFlagSet != 0) {
17799                             perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
17800                         }
17801                     }
17802                 } else {
17803                     // Need to wait for post-restore install to apply the grant
17804                     if (DEBUG_BACKUP) {
17805                         Slog.v(TAG, "        - not yet installed; saving for later");
17806                     }
17807                     mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
17808                             isGranted, newFlagSet, userId);
17809                 }
17810             } else {
17811                 PackageManagerService.reportSettingsProblem(Log.WARN,
17812                         "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
17813                 XmlUtils.skipCurrentTag(parser);
17814             }
17815         }
17816
17817         scheduleWriteSettingsLocked();
17818         mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17819     }
17820
17821     @Override
17822     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
17823             int sourceUserId, int targetUserId, int flags) {
17824         mContext.enforceCallingOrSelfPermission(
17825                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17826         int callingUid = Binder.getCallingUid();
17827         enforceOwnerRights(ownerPackage, callingUid);
17828         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17829         if (intentFilter.countActions() == 0) {
17830             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
17831             return;
17832         }
17833         synchronized (mPackages) {
17834             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
17835                     ownerPackage, targetUserId, flags);
17836             CrossProfileIntentResolver resolver =
17837                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17838             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
17839             // We have all those whose filter is equal. Now checking if the rest is equal as well.
17840             if (existing != null) {
17841                 int size = existing.size();
17842                 for (int i = 0; i < size; i++) {
17843                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
17844                         return;
17845                     }
17846                 }
17847             }
17848             resolver.addFilter(newFilter);
17849             scheduleWritePackageRestrictionsLocked(sourceUserId);
17850         }
17851     }
17852
17853     @Override
17854     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
17855         mContext.enforceCallingOrSelfPermission(
17856                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17857         int callingUid = Binder.getCallingUid();
17858         enforceOwnerRights(ownerPackage, callingUid);
17859         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17860         synchronized (mPackages) {
17861             CrossProfileIntentResolver resolver =
17862                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17863             ArraySet<CrossProfileIntentFilter> set =
17864                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
17865             for (CrossProfileIntentFilter filter : set) {
17866                 if (filter.getOwnerPackage().equals(ownerPackage)) {
17867                     resolver.removeFilter(filter);
17868                 }
17869             }
17870             scheduleWritePackageRestrictionsLocked(sourceUserId);
17871         }
17872     }
17873
17874     // Enforcing that callingUid is owning pkg on userId
17875     private void enforceOwnerRights(String pkg, int callingUid) {
17876         // The system owns everything.
17877         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17878             return;
17879         }
17880         int callingUserId = UserHandle.getUserId(callingUid);
17881         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
17882         if (pi == null) {
17883             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
17884                     + callingUserId);
17885         }
17886         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
17887             throw new SecurityException("Calling uid " + callingUid
17888                     + " does not own package " + pkg);
17889         }
17890     }
17891
17892     @Override
17893     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
17894         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
17895     }
17896
17897     private Intent getHomeIntent() {
17898         Intent intent = new Intent(Intent.ACTION_MAIN);
17899         intent.addCategory(Intent.CATEGORY_HOME);
17900         intent.addCategory(Intent.CATEGORY_DEFAULT);
17901         return intent;
17902     }
17903
17904     private IntentFilter getHomeFilter() {
17905         IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
17906         filter.addCategory(Intent.CATEGORY_HOME);
17907         filter.addCategory(Intent.CATEGORY_DEFAULT);
17908         return filter;
17909     }
17910
17911     ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
17912             int userId) {
17913         Intent intent  = getHomeIntent();
17914         List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
17915                 PackageManager.GET_META_DATA, userId);
17916         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
17917                 true, false, false, userId);
17918
17919         allHomeCandidates.clear();
17920         if (list != null) {
17921             for (ResolveInfo ri : list) {
17922                 allHomeCandidates.add(ri);
17923             }
17924         }
17925         return (preferred == null || preferred.activityInfo == null)
17926                 ? null
17927                 : new ComponentName(preferred.activityInfo.packageName,
17928                         preferred.activityInfo.name);
17929     }
17930
17931     @Override
17932     public void setHomeActivity(ComponentName comp, int userId) {
17933         ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
17934         getHomeActivitiesAsUser(homeActivities, userId);
17935
17936         boolean found = false;
17937
17938         final int size = homeActivities.size();
17939         final ComponentName[] set = new ComponentName[size];
17940         for (int i = 0; i < size; i++) {
17941             final ResolveInfo candidate = homeActivities.get(i);
17942             final ActivityInfo info = candidate.activityInfo;
17943             final ComponentName activityName = new ComponentName(info.packageName, info.name);
17944             set[i] = activityName;
17945             if (!found && activityName.equals(comp)) {
17946                 found = true;
17947             }
17948         }
17949         if (!found) {
17950             throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
17951                     + userId);
17952         }
17953         replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
17954                 set, comp, userId);
17955     }
17956
17957     private @Nullable String getSetupWizardPackageName() {
17958         final Intent intent = new Intent(Intent.ACTION_MAIN);
17959         intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
17960
17961         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
17962                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
17963                         | MATCH_DISABLED_COMPONENTS,
17964                 UserHandle.myUserId());
17965         if (matches.size() == 1) {
17966             return matches.get(0).getComponentInfo().packageName;
17967         } else {
17968             Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
17969                     + ": matches=" + matches);
17970             return null;
17971         }
17972     }
17973
17974     private @Nullable String getStorageManagerPackageName() {
17975         final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
17976
17977         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
17978                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
17979                         | MATCH_DISABLED_COMPONENTS,
17980                 UserHandle.myUserId());
17981         if (matches.size() == 1) {
17982             return matches.get(0).getComponentInfo().packageName;
17983         } else {
17984             Slog.e(TAG, "There should probably be exactly one storage manager; found "
17985                     + matches.size() + ": matches=" + matches);
17986             return null;
17987         }
17988     }
17989
17990     @Override
17991     public void setApplicationEnabledSetting(String appPackageName,
17992             int newState, int flags, int userId, String callingPackage) {
17993         if (!sUserManager.exists(userId)) return;
17994         if (callingPackage == null) {
17995             callingPackage = Integer.toString(Binder.getCallingUid());
17996         }
17997         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
17998     }
17999
18000     @Override
18001     public void setComponentEnabledSetting(ComponentName componentName,
18002             int newState, int flags, int userId) {
18003         if (!sUserManager.exists(userId)) return;
18004         setEnabledSetting(componentName.getPackageName(),
18005                 componentName.getClassName(), newState, flags, userId, null);
18006     }
18007
18008     private void setEnabledSetting(final String packageName, String className, int newState,
18009             final int flags, int userId, String callingPackage) {
18010         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
18011               || newState == COMPONENT_ENABLED_STATE_ENABLED
18012               || newState == COMPONENT_ENABLED_STATE_DISABLED
18013               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
18014               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
18015             throw new IllegalArgumentException("Invalid new component state: "
18016                     + newState);
18017         }
18018         PackageSetting pkgSetting;
18019         final int uid = Binder.getCallingUid();
18020         final int permission;
18021         if (uid == Process.SYSTEM_UID) {
18022             permission = PackageManager.PERMISSION_GRANTED;
18023         } else {
18024             permission = mContext.checkCallingOrSelfPermission(
18025                     android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
18026         }
18027         enforceCrossUserPermission(uid, userId,
18028                 false /* requireFullPermission */, true /* checkShell */, "set enabled");
18029         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
18030         boolean sendNow = false;
18031         boolean isApp = (className == null);
18032         String componentName = isApp ? packageName : className;
18033         int packageUid = -1;
18034         ArrayList<String> components;
18035
18036         // writer
18037         synchronized (mPackages) {
18038             pkgSetting = mSettings.mPackages.get(packageName);
18039             if (pkgSetting == null) {
18040                 if (className == null) {
18041                     throw new IllegalArgumentException("Unknown package: " + packageName);
18042                 }
18043                 throw new IllegalArgumentException(
18044                         "Unknown component: " + packageName + "/" + className);
18045             }
18046         }
18047
18048         // Limit who can change which apps
18049         if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
18050             // Don't allow apps that don't have permission to modify other apps
18051             if (!allowedByPermission) {
18052                 throw new SecurityException(
18053                         "Permission Denial: attempt to change component state from pid="
18054                         + Binder.getCallingPid()
18055                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
18056             }
18057             // Don't allow changing protected packages.
18058             if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
18059                 throw new SecurityException("Cannot disable a protected package: " + packageName);
18060             }
18061         }
18062
18063         synchronized (mPackages) {
18064             if (uid == Process.SHELL_UID) {
18065                 // Shell can only change whole packages between ENABLED and DISABLED_USER states
18066                 int oldState = pkgSetting.getEnabled(userId);
18067                 if (className == null
18068                     &&
18069                     (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
18070                      || oldState == COMPONENT_ENABLED_STATE_DEFAULT
18071                      || oldState == COMPONENT_ENABLED_STATE_ENABLED)
18072                     &&
18073                     (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
18074                      || newState == COMPONENT_ENABLED_STATE_DEFAULT
18075                      || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
18076                     // ok
18077                 } else {
18078                     throw new SecurityException(
18079                             "Shell cannot change component state for " + packageName + "/"
18080                             + className + " to " + newState);
18081                 }
18082             }
18083             if (className == null) {
18084                 // We're dealing with an application/package level state change
18085                 if (pkgSetting.getEnabled(userId) == newState) {
18086                     // Nothing to do
18087                     return;
18088                 }
18089                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
18090                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
18091                     // Don't care about who enables an app.
18092                     callingPackage = null;
18093                 }
18094                 pkgSetting.setEnabled(newState, userId, callingPackage);
18095                 // pkgSetting.pkg.mSetEnabled = newState;
18096             } else {
18097                 // We're dealing with a component level state change
18098                 // First, verify that this is a valid class name.
18099                 PackageParser.Package pkg = pkgSetting.pkg;
18100                 if (pkg == null || !pkg.hasComponentClassName(className)) {
18101                     if (pkg != null &&
18102                             pkg.applicationInfo.targetSdkVersion >=
18103                                     Build.VERSION_CODES.JELLY_BEAN) {
18104                         throw new IllegalArgumentException("Component class " + className
18105                                 + " does not exist in " + packageName);
18106                     } else {
18107                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
18108                                 + className + " does not exist in " + packageName);
18109                     }
18110                 }
18111                 switch (newState) {
18112                 case COMPONENT_ENABLED_STATE_ENABLED:
18113                     if (!pkgSetting.enableComponentLPw(className, userId)) {
18114                         return;
18115                     }
18116                     break;
18117                 case COMPONENT_ENABLED_STATE_DISABLED:
18118                     if (!pkgSetting.disableComponentLPw(className, userId)) {
18119                         return;
18120                     }
18121                     break;
18122                 case COMPONENT_ENABLED_STATE_DEFAULT:
18123                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
18124                         return;
18125                     }
18126                     break;
18127                 default:
18128                     Slog.e(TAG, "Invalid new component state: " + newState);
18129                     return;
18130                 }
18131             }
18132             scheduleWritePackageRestrictionsLocked(userId);
18133             components = mPendingBroadcasts.get(userId, packageName);
18134             final boolean newPackage = components == null;
18135             if (newPackage) {
18136                 components = new ArrayList<String>();
18137             }
18138             if (!components.contains(componentName)) {
18139                 components.add(componentName);
18140             }
18141             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
18142                 sendNow = true;
18143                 // Purge entry from pending broadcast list if another one exists already
18144                 // since we are sending one right away.
18145                 mPendingBroadcasts.remove(userId, packageName);
18146             } else {
18147                 if (newPackage) {
18148                     mPendingBroadcasts.put(userId, packageName, components);
18149                 }
18150                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
18151                     // Schedule a message
18152                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
18153                 }
18154             }
18155         }
18156
18157         long callingId = Binder.clearCallingIdentity();
18158         try {
18159             if (sendNow) {
18160                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
18161                 sendPackageChangedBroadcast(packageName,
18162                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
18163             }
18164         } finally {
18165             Binder.restoreCallingIdentity(callingId);
18166         }
18167     }
18168
18169     @Override
18170     public void flushPackageRestrictionsAsUser(int userId) {
18171         if (!sUserManager.exists(userId)) {
18172             return;
18173         }
18174         enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
18175                 false /* checkShell */, "flushPackageRestrictions");
18176         synchronized (mPackages) {
18177             mSettings.writePackageRestrictionsLPr(userId);
18178             mDirtyUsers.remove(userId);
18179             if (mDirtyUsers.isEmpty()) {
18180                 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
18181             }
18182         }
18183     }
18184
18185     private void sendPackageChangedBroadcast(String packageName,
18186             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
18187         if (DEBUG_INSTALL)
18188             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
18189                     + componentNames);
18190         Bundle extras = new Bundle(4);
18191         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
18192         String nameList[] = new String[componentNames.size()];
18193         componentNames.toArray(nameList);
18194         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
18195         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
18196         extras.putInt(Intent.EXTRA_UID, packageUid);
18197         // If this is not reporting a change of the overall package, then only send it
18198         // to registered receivers.  We don't want to launch a swath of apps for every
18199         // little component state change.
18200         final int flags = !componentNames.contains(packageName)
18201                 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
18202         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
18203                 new int[] {UserHandle.getUserId(packageUid)});
18204     }
18205
18206     @Override
18207     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
18208         if (!sUserManager.exists(userId)) return;
18209         final int uid = Binder.getCallingUid();
18210         final int permission = mContext.checkCallingOrSelfPermission(
18211                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
18212         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
18213         enforceCrossUserPermission(uid, userId,
18214                 true /* requireFullPermission */, true /* checkShell */, "stop package");
18215         // writer
18216         synchronized (mPackages) {
18217             if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
18218                     allowedByPermission, uid, userId)) {
18219                 scheduleWritePackageRestrictionsLocked(userId);
18220             }
18221         }
18222     }
18223
18224     @Override
18225     public String getInstallerPackageName(String packageName) {
18226         // reader
18227         synchronized (mPackages) {
18228             return mSettings.getInstallerPackageNameLPr(packageName);
18229         }
18230     }
18231
18232     public boolean isOrphaned(String packageName) {
18233         // reader
18234         synchronized (mPackages) {
18235             return mSettings.isOrphaned(packageName);
18236         }
18237     }
18238
18239     @Override
18240     public int getApplicationEnabledSetting(String packageName, int userId) {
18241         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
18242         int uid = Binder.getCallingUid();
18243         enforceCrossUserPermission(uid, userId,
18244                 false /* requireFullPermission */, false /* checkShell */, "get enabled");
18245         // reader
18246         synchronized (mPackages) {
18247             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
18248         }
18249     }
18250
18251     @Override
18252     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
18253         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
18254         int uid = Binder.getCallingUid();
18255         enforceCrossUserPermission(uid, userId,
18256                 false /* requireFullPermission */, false /* checkShell */, "get component enabled");
18257         // reader
18258         synchronized (mPackages) {
18259             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
18260         }
18261     }
18262
18263     @Override
18264     public void enterSafeMode() {
18265         enforceSystemOrRoot("Only the system can request entering safe mode");
18266
18267         if (!mSystemReady) {
18268             mSafeMode = true;
18269         }
18270     }
18271
18272     @Override
18273     public void systemReady() {
18274         mSystemReady = true;
18275
18276         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
18277         // disabled after already being started.
18278         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
18279                 mContext.getContentResolver(), UserHandle.USER_SYSTEM);
18280
18281         // Read the compatibilty setting when the system is ready.
18282         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
18283                 mContext.getContentResolver(),
18284                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
18285         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
18286         if (DEBUG_SETTINGS) {
18287             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
18288         }
18289
18290         int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
18291
18292         synchronized (mPackages) {
18293             // Verify that all of the preferred activity components actually
18294             // exist.  It is possible for applications to be updated and at
18295             // that point remove a previously declared activity component that
18296             // had been set as a preferred activity.  We try to clean this up
18297             // the next time we encounter that preferred activity, but it is
18298             // possible for the user flow to never be able to return to that
18299             // situation so here we do a sanity check to make sure we haven't
18300             // left any junk around.
18301             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
18302             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18303                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18304                 removed.clear();
18305                 for (PreferredActivity pa : pir.filterSet()) {
18306                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
18307                         removed.add(pa);
18308                     }
18309                 }
18310                 if (removed.size() > 0) {
18311                     for (int r=0; r<removed.size(); r++) {
18312                         PreferredActivity pa = removed.get(r);
18313                         Slog.w(TAG, "Removing dangling preferred activity: "
18314                                 + pa.mPref.mComponent);
18315                         pir.removeFilter(pa);
18316                     }
18317                     mSettings.writePackageRestrictionsLPr(
18318                             mSettings.mPreferredActivities.keyAt(i));
18319                 }
18320             }
18321
18322             for (int userId : UserManagerService.getInstance().getUserIds()) {
18323                 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
18324                     grantPermissionsUserIds = ArrayUtils.appendInt(
18325                             grantPermissionsUserIds, userId);
18326                 }
18327             }
18328         }
18329         sUserManager.systemReady();
18330
18331         // If we upgraded grant all default permissions before kicking off.
18332         for (int userId : grantPermissionsUserIds) {
18333             mDefaultPermissionPolicy.grantDefaultPermissions(userId);
18334         }
18335
18336         // If we did not grant default permissions, we preload from this the
18337         // default permission exceptions lazily to ensure we don't hit the
18338         // disk on a new user creation.
18339         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
18340             mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
18341         }
18342
18343         // Kick off any messages waiting for system ready
18344         if (mPostSystemReadyMessages != null) {
18345             for (Message msg : mPostSystemReadyMessages) {
18346                 msg.sendToTarget();
18347             }
18348             mPostSystemReadyMessages = null;
18349         }
18350
18351         // Watch for external volumes that come and go over time
18352         final StorageManager storage = mContext.getSystemService(StorageManager.class);
18353         storage.registerListener(mStorageListener);
18354
18355         mInstallerService.systemReady();
18356         mPackageDexOptimizer.systemReady();
18357
18358         MountServiceInternal mountServiceInternal = LocalServices.getService(
18359                 MountServiceInternal.class);
18360         mountServiceInternal.addExternalStoragePolicy(
18361                 new MountServiceInternal.ExternalStorageMountPolicy() {
18362             @Override
18363             public int getMountMode(int uid, String packageName) {
18364                 if (Process.isIsolated(uid)) {
18365                     return Zygote.MOUNT_EXTERNAL_NONE;
18366                 }
18367                 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
18368                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
18369                 }
18370                 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
18371                     return Zygote.MOUNT_EXTERNAL_DEFAULT;
18372                 }
18373                 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
18374                     return Zygote.MOUNT_EXTERNAL_READ;
18375                 }
18376                 return Zygote.MOUNT_EXTERNAL_WRITE;
18377             }
18378
18379             @Override
18380             public boolean hasExternalStorage(int uid, String packageName) {
18381                 return true;
18382             }
18383         });
18384
18385         // Now that we're mostly running, clean up stale users and apps
18386         reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
18387         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
18388     }
18389
18390     @Override
18391     public boolean isSafeMode() {
18392         return mSafeMode;
18393     }
18394
18395     @Override
18396     public boolean hasSystemUidErrors() {
18397         return mHasSystemUidErrors;
18398     }
18399
18400     static String arrayToString(int[] array) {
18401         StringBuffer buf = new StringBuffer(128);
18402         buf.append('[');
18403         if (array != null) {
18404             for (int i=0; i<array.length; i++) {
18405                 if (i > 0) buf.append(", ");
18406                 buf.append(array[i]);
18407             }
18408         }
18409         buf.append(']');
18410         return buf.toString();
18411     }
18412
18413     static class DumpState {
18414         public static final int DUMP_LIBS = 1 << 0;
18415         public static final int DUMP_FEATURES = 1 << 1;
18416         public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
18417         public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
18418         public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
18419         public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
18420         public static final int DUMP_PERMISSIONS = 1 << 6;
18421         public static final int DUMP_PACKAGES = 1 << 7;
18422         public static final int DUMP_SHARED_USERS = 1 << 8;
18423         public static final int DUMP_MESSAGES = 1 << 9;
18424         public static final int DUMP_PROVIDERS = 1 << 10;
18425         public static final int DUMP_VERIFIERS = 1 << 11;
18426         public static final int DUMP_PREFERRED = 1 << 12;
18427         public static final int DUMP_PREFERRED_XML = 1 << 13;
18428         public static final int DUMP_KEYSETS = 1 << 14;
18429         public static final int DUMP_VERSION = 1 << 15;
18430         public static final int DUMP_INSTALLS = 1 << 16;
18431         public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
18432         public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
18433         public static final int DUMP_FROZEN = 1 << 19;
18434         public static final int DUMP_DEXOPT = 1 << 20;
18435         public static final int DUMP_COMPILER_STATS = 1 << 21;
18436
18437         public static final int OPTION_SHOW_FILTERS = 1 << 0;
18438
18439         private int mTypes;
18440
18441         private int mOptions;
18442
18443         private boolean mTitlePrinted;
18444
18445         private SharedUserSetting mSharedUser;
18446
18447         public boolean isDumping(int type) {
18448             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
18449                 return true;
18450             }
18451
18452             return (mTypes & type) != 0;
18453         }
18454
18455         public void setDump(int type) {
18456             mTypes |= type;
18457         }
18458
18459         public boolean isOptionEnabled(int option) {
18460             return (mOptions & option) != 0;
18461         }
18462
18463         public void setOptionEnabled(int option) {
18464             mOptions |= option;
18465         }
18466
18467         public boolean onTitlePrinted() {
18468             final boolean printed = mTitlePrinted;
18469             mTitlePrinted = true;
18470             return printed;
18471         }
18472
18473         public boolean getTitlePrinted() {
18474             return mTitlePrinted;
18475         }
18476
18477         public void setTitlePrinted(boolean enabled) {
18478             mTitlePrinted = enabled;
18479         }
18480
18481         public SharedUserSetting getSharedUser() {
18482             return mSharedUser;
18483         }
18484
18485         public void setSharedUser(SharedUserSetting user) {
18486             mSharedUser = user;
18487         }
18488     }
18489
18490     @Override
18491     public void onShellCommand(FileDescriptor in, FileDescriptor out,
18492             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
18493         (new PackageManagerShellCommand(this)).exec(
18494                 this, in, out, err, args, resultReceiver);
18495     }
18496
18497     @Override
18498     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
18499         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
18500                 != PackageManager.PERMISSION_GRANTED) {
18501             pw.println("Permission Denial: can't dump ActivityManager from from pid="
18502                     + Binder.getCallingPid()
18503                     + ", uid=" + Binder.getCallingUid()
18504                     + " without permission "
18505                     + android.Manifest.permission.DUMP);
18506             return;
18507         }
18508
18509         DumpState dumpState = new DumpState();
18510         boolean fullPreferred = false;
18511         boolean checkin = false;
18512
18513         String packageName = null;
18514         ArraySet<String> permissionNames = null;
18515
18516         int opti = 0;
18517         while (opti < args.length) {
18518             String opt = args[opti];
18519             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18520                 break;
18521             }
18522             opti++;
18523
18524             if ("-a".equals(opt)) {
18525                 // Right now we only know how to print all.
18526             } else if ("-h".equals(opt)) {
18527                 pw.println("Package manager dump options:");
18528                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
18529                 pw.println("    --checkin: dump for a checkin");
18530                 pw.println("    -f: print details of intent filters");
18531                 pw.println("    -h: print this help");
18532                 pw.println("  cmd may be one of:");
18533                 pw.println("    l[ibraries]: list known shared libraries");
18534                 pw.println("    f[eatures]: list device features");
18535                 pw.println("    k[eysets]: print known keysets");
18536                 pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
18537                 pw.println("    perm[issions]: dump permissions");
18538                 pw.println("    permission [name ...]: dump declaration and use of given permission");
18539                 pw.println("    pref[erred]: print preferred package settings");
18540                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
18541                 pw.println("    prov[iders]: dump content providers");
18542                 pw.println("    p[ackages]: dump installed packages");
18543                 pw.println("    s[hared-users]: dump shared user IDs");
18544                 pw.println("    m[essages]: print collected runtime messages");
18545                 pw.println("    v[erifiers]: print package verifier info");
18546                 pw.println("    d[omain-preferred-apps]: print domains preferred apps");
18547                 pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
18548                 pw.println("    version: print database version info");
18549                 pw.println("    write: write current settings now");
18550                 pw.println("    installs: details about install sessions");
18551                 pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
18552                 pw.println("    dexopt: dump dexopt state");
18553                 pw.println("    compiler-stats: dump compiler statistics");
18554                 pw.println("    <package.name>: info about given package");
18555                 return;
18556             } else if ("--checkin".equals(opt)) {
18557                 checkin = true;
18558             } else if ("-f".equals(opt)) {
18559                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18560             } else {
18561                 pw.println("Unknown argument: " + opt + "; use -h for help");
18562             }
18563         }
18564
18565         // Is the caller requesting to dump a particular piece of data?
18566         if (opti < args.length) {
18567             String cmd = args[opti];
18568             opti++;
18569             // Is this a package name?
18570             if ("android".equals(cmd) || cmd.contains(".")) {
18571                 packageName = cmd;
18572                 // When dumping a single package, we always dump all of its
18573                 // filter information since the amount of data will be reasonable.
18574                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18575             } else if ("check-permission".equals(cmd)) {
18576                 if (opti >= args.length) {
18577                     pw.println("Error: check-permission missing permission argument");
18578                     return;
18579                 }
18580                 String perm = args[opti];
18581                 opti++;
18582                 if (opti >= args.length) {
18583                     pw.println("Error: check-permission missing package argument");
18584                     return;
18585                 }
18586                 String pkg = args[opti];
18587                 opti++;
18588                 int user = UserHandle.getUserId(Binder.getCallingUid());
18589                 if (opti < args.length) {
18590                     try {
18591                         user = Integer.parseInt(args[opti]);
18592                     } catch (NumberFormatException e) {
18593                         pw.println("Error: check-permission user argument is not a number: "
18594                                 + args[opti]);
18595                         return;
18596                     }
18597                 }
18598                 pw.println(checkPermission(perm, pkg, user));
18599                 return;
18600             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
18601                 dumpState.setDump(DumpState.DUMP_LIBS);
18602             } else if ("f".equals(cmd) || "features".equals(cmd)) {
18603                 dumpState.setDump(DumpState.DUMP_FEATURES);
18604             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
18605                 if (opti >= args.length) {
18606                     dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
18607                             | DumpState.DUMP_SERVICE_RESOLVERS
18608                             | DumpState.DUMP_RECEIVER_RESOLVERS
18609                             | DumpState.DUMP_CONTENT_RESOLVERS);
18610                 } else {
18611                     while (opti < args.length) {
18612                         String name = args[opti];
18613                         if ("a".equals(name) || "activity".equals(name)) {
18614                             dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
18615                         } else if ("s".equals(name) || "service".equals(name)) {
18616                             dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
18617                         } else if ("r".equals(name) || "receiver".equals(name)) {
18618                             dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
18619                         } else if ("c".equals(name) || "content".equals(name)) {
18620                             dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
18621                         } else {
18622                             pw.println("Error: unknown resolver table type: " + name);
18623                             return;
18624                         }
18625                         opti++;
18626                     }
18627                 }
18628             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
18629                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
18630             } else if ("permission".equals(cmd)) {
18631                 if (opti >= args.length) {
18632                     pw.println("Error: permission requires permission name");
18633                     return;
18634                 }
18635                 permissionNames = new ArraySet<>();
18636                 while (opti < args.length) {
18637                     permissionNames.add(args[opti]);
18638                     opti++;
18639                 }
18640                 dumpState.setDump(DumpState.DUMP_PERMISSIONS
18641                         | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
18642             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
18643                 dumpState.setDump(DumpState.DUMP_PREFERRED);
18644             } else if ("preferred-xml".equals(cmd)) {
18645                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
18646                 if (opti < args.length && "--full".equals(args[opti])) {
18647                     fullPreferred = true;
18648                     opti++;
18649                 }
18650             } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
18651                 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
18652             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
18653                 dumpState.setDump(DumpState.DUMP_PACKAGES);
18654             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
18655                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
18656             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
18657                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
18658             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
18659                 dumpState.setDump(DumpState.DUMP_MESSAGES);
18660             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
18661                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
18662             } else if ("i".equals(cmd) || "ifv".equals(cmd)
18663                     || "intent-filter-verifiers".equals(cmd)) {
18664                 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
18665             } else if ("version".equals(cmd)) {
18666                 dumpState.setDump(DumpState.DUMP_VERSION);
18667             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
18668                 dumpState.setDump(DumpState.DUMP_KEYSETS);
18669             } else if ("installs".equals(cmd)) {
18670                 dumpState.setDump(DumpState.DUMP_INSTALLS);
18671             } else if ("frozen".equals(cmd)) {
18672                 dumpState.setDump(DumpState.DUMP_FROZEN);
18673             } else if ("dexopt".equals(cmd)) {
18674                 dumpState.setDump(DumpState.DUMP_DEXOPT);
18675             } else if ("compiler-stats".equals(cmd)) {
18676                 dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
18677             } else if ("write".equals(cmd)) {
18678                 synchronized (mPackages) {
18679                     mSettings.writeLPr();
18680                     pw.println("Settings written.");
18681                     return;
18682                 }
18683             }
18684         }
18685
18686         if (checkin) {
18687             pw.println("vers,1");
18688         }
18689
18690         // reader
18691         synchronized (mPackages) {
18692             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
18693                 if (!checkin) {
18694                     if (dumpState.onTitlePrinted())
18695                         pw.println();
18696                     pw.println("Database versions:");
18697                     mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
18698                 }
18699             }
18700
18701             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
18702                 if (!checkin) {
18703                     if (dumpState.onTitlePrinted())
18704                         pw.println();
18705                     pw.println("Verifiers:");
18706                     pw.print("  Required: ");
18707                     pw.print(mRequiredVerifierPackage);
18708                     pw.print(" (uid=");
18709                     pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18710                             UserHandle.USER_SYSTEM));
18711                     pw.println(")");
18712                 } else if (mRequiredVerifierPackage != null) {
18713                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
18714                     pw.print(",");
18715                     pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18716                             UserHandle.USER_SYSTEM));
18717                 }
18718             }
18719
18720             if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
18721                     packageName == null) {
18722                 if (mIntentFilterVerifierComponent != null) {
18723                     String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
18724                     if (!checkin) {
18725                         if (dumpState.onTitlePrinted())
18726                             pw.println();
18727                         pw.println("Intent Filter Verifier:");
18728                         pw.print("  Using: ");
18729                         pw.print(verifierPackageName);
18730                         pw.print(" (uid=");
18731                         pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18732                                 UserHandle.USER_SYSTEM));
18733                         pw.println(")");
18734                     } else if (verifierPackageName != null) {
18735                         pw.print("ifv,"); pw.print(verifierPackageName);
18736                         pw.print(",");
18737                         pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18738                                 UserHandle.USER_SYSTEM));
18739                     }
18740                 } else {
18741                     pw.println();
18742                     pw.println("No Intent Filter Verifier available!");
18743                 }
18744             }
18745
18746             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
18747                 boolean printedHeader = false;
18748                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
18749                 while (it.hasNext()) {
18750                     String name = it.next();
18751                     SharedLibraryEntry ent = mSharedLibraries.get(name);
18752                     if (!checkin) {
18753                         if (!printedHeader) {
18754                             if (dumpState.onTitlePrinted())
18755                                 pw.println();
18756                             pw.println("Libraries:");
18757                             printedHeader = true;
18758                         }
18759                         pw.print("  ");
18760                     } else {
18761                         pw.print("lib,");
18762                     }
18763                     pw.print(name);
18764                     if (!checkin) {
18765                         pw.print(" -> ");
18766                     }
18767                     if (ent.path != null) {
18768                         if (!checkin) {
18769                             pw.print("(jar) ");
18770                             pw.print(ent.path);
18771                         } else {
18772                             pw.print(",jar,");
18773                             pw.print(ent.path);
18774                         }
18775                     } else {
18776                         if (!checkin) {
18777                             pw.print("(apk) ");
18778                             pw.print(ent.apk);
18779                         } else {
18780                             pw.print(",apk,");
18781                             pw.print(ent.apk);
18782                         }
18783                     }
18784                     pw.println();
18785                 }
18786             }
18787
18788             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
18789                 if (dumpState.onTitlePrinted())
18790                     pw.println();
18791                 if (!checkin) {
18792                     pw.println("Features:");
18793                 }
18794
18795                 for (FeatureInfo feat : mAvailableFeatures.values()) {
18796                     if (checkin) {
18797                         pw.print("feat,");
18798                         pw.print(feat.name);
18799                         pw.print(",");
18800                         pw.println(feat.version);
18801                     } else {
18802                         pw.print("  ");
18803                         pw.print(feat.name);
18804                         if (feat.version > 0) {
18805                             pw.print(" version=");
18806                             pw.print(feat.version);
18807                         }
18808                         pw.println();
18809                     }
18810                 }
18811             }
18812
18813             if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
18814                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
18815                         : "Activity Resolver Table:", "  ", packageName,
18816                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18817                     dumpState.setTitlePrinted(true);
18818                 }
18819             }
18820             if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
18821                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
18822                         : "Receiver Resolver Table:", "  ", packageName,
18823                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18824                     dumpState.setTitlePrinted(true);
18825                 }
18826             }
18827             if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
18828                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
18829                         : "Service Resolver Table:", "  ", packageName,
18830                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18831                     dumpState.setTitlePrinted(true);
18832                 }
18833             }
18834             if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
18835                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
18836                         : "Provider Resolver Table:", "  ", packageName,
18837                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18838                     dumpState.setTitlePrinted(true);
18839                 }
18840             }
18841
18842             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
18843                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18844                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18845                     int user = mSettings.mPreferredActivities.keyAt(i);
18846                     if (pir.dump(pw,
18847                             dumpState.getTitlePrinted()
18848                                 ? "\nPreferred Activities User " + user + ":"
18849                                 : "Preferred Activities User " + user + ":", "  ",
18850                             packageName, true, false)) {
18851                         dumpState.setTitlePrinted(true);
18852                     }
18853                 }
18854             }
18855
18856             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
18857                 pw.flush();
18858                 FileOutputStream fout = new FileOutputStream(fd);
18859                 BufferedOutputStream str = new BufferedOutputStream(fout);
18860                 XmlSerializer serializer = new FastXmlSerializer();
18861                 try {
18862                     serializer.setOutput(str, StandardCharsets.UTF_8.name());
18863                     serializer.startDocument(null, true);
18864                     serializer.setFeature(
18865                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
18866                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
18867                     serializer.endDocument();
18868                     serializer.flush();
18869                 } catch (IllegalArgumentException e) {
18870                     pw.println("Failed writing: " + e);
18871                 } catch (IllegalStateException e) {
18872                     pw.println("Failed writing: " + e);
18873                 } catch (IOException e) {
18874                     pw.println("Failed writing: " + e);
18875                 }
18876             }
18877
18878             if (!checkin
18879                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
18880                     && packageName == null) {
18881                 pw.println();
18882                 int count = mSettings.mPackages.size();
18883                 if (count == 0) {
18884                     pw.println("No applications!");
18885                     pw.println();
18886                 } else {
18887                     final String prefix = "  ";
18888                     Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
18889                     if (allPackageSettings.size() == 0) {
18890                         pw.println("No domain preferred apps!");
18891                         pw.println();
18892                     } else {
18893                         pw.println("App verification status:");
18894                         pw.println();
18895                         count = 0;
18896                         for (PackageSetting ps : allPackageSettings) {
18897                             IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
18898                             if (ivi == null || ivi.getPackageName() == null) continue;
18899                             pw.println(prefix + "Package: " + ivi.getPackageName());
18900                             pw.println(prefix + "Domains: " + ivi.getDomainsString());
18901                             pw.println(prefix + "Status:  " + ivi.getStatusString());
18902                             pw.println();
18903                             count++;
18904                         }
18905                         if (count == 0) {
18906                             pw.println(prefix + "No app verification established.");
18907                             pw.println();
18908                         }
18909                         for (int userId : sUserManager.getUserIds()) {
18910                             pw.println("App linkages for user " + userId + ":");
18911                             pw.println();
18912                             count = 0;
18913                             for (PackageSetting ps : allPackageSettings) {
18914                                 final long status = ps.getDomainVerificationStatusForUser(userId);
18915                                 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
18916                                     continue;
18917                                 }
18918                                 pw.println(prefix + "Package: " + ps.name);
18919                                 pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
18920                                 String statusStr = IntentFilterVerificationInfo.
18921                                         getStatusStringFromValue(status);
18922                                 pw.println(prefix + "Status:  " + statusStr);
18923                                 pw.println();
18924                                 count++;
18925                             }
18926                             if (count == 0) {
18927                                 pw.println(prefix + "No configured app linkages.");
18928                                 pw.println();
18929                             }
18930                         }
18931                     }
18932                 }
18933             }
18934
18935             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
18936                 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
18937                 if (packageName == null && permissionNames == null) {
18938                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
18939                         if (iperm == 0) {
18940                             if (dumpState.onTitlePrinted())
18941                                 pw.println();
18942                             pw.println("AppOp Permissions:");
18943                         }
18944                         pw.print("  AppOp Permission ");
18945                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
18946                         pw.println(":");
18947                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
18948                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
18949                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
18950                         }
18951                     }
18952                 }
18953             }
18954
18955             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
18956                 boolean printedSomething = false;
18957                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
18958                     if (packageName != null && !packageName.equals(p.info.packageName)) {
18959                         continue;
18960                     }
18961                     if (!printedSomething) {
18962                         if (dumpState.onTitlePrinted())
18963                             pw.println();
18964                         pw.println("Registered ContentProviders:");
18965                         printedSomething = true;
18966                     }
18967                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
18968                     pw.print("    "); pw.println(p.toString());
18969                 }
18970                 printedSomething = false;
18971                 for (Map.Entry<String, PackageParser.Provider> entry :
18972                         mProvidersByAuthority.entrySet()) {
18973                     PackageParser.Provider p = entry.getValue();
18974                     if (packageName != null && !packageName.equals(p.info.packageName)) {
18975                         continue;
18976                     }
18977                     if (!printedSomething) {
18978                         if (dumpState.onTitlePrinted())
18979                             pw.println();
18980                         pw.println("ContentProvider Authorities:");
18981                         printedSomething = true;
18982                     }
18983                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
18984                     pw.print("    "); pw.println(p.toString());
18985                     if (p.info != null && p.info.applicationInfo != null) {
18986                         final String appInfo = p.info.applicationInfo.toString();
18987                         pw.print("      applicationInfo="); pw.println(appInfo);
18988                     }
18989                 }
18990             }
18991
18992             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
18993                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
18994             }
18995
18996             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
18997                 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
18998             }
18999
19000             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
19001                 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
19002             }
19003
19004             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
19005                 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
19006             }
19007
19008             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
19009                 // XXX should handle packageName != null by dumping only install data that
19010                 // the given package is involved with.
19011                 if (dumpState.onTitlePrinted()) pw.println();
19012                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
19013             }
19014
19015             if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
19016                 // XXX should handle packageName != null by dumping only install data that
19017                 // the given package is involved with.
19018                 if (dumpState.onTitlePrinted()) pw.println();
19019
19020                 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
19021                 ipw.println();
19022                 ipw.println("Frozen packages:");
19023                 ipw.increaseIndent();
19024                 if (mFrozenPackages.size() == 0) {
19025                     ipw.println("(none)");
19026                 } else {
19027                     for (int i = 0; i < mFrozenPackages.size(); i++) {
19028                         ipw.println(mFrozenPackages.valueAt(i));
19029                     }
19030                 }
19031                 ipw.decreaseIndent();
19032             }
19033
19034             if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
19035                 if (dumpState.onTitlePrinted()) pw.println();
19036                 dumpDexoptStateLPr(pw, packageName);
19037             }
19038
19039             if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
19040                 if (dumpState.onTitlePrinted()) pw.println();
19041                 dumpCompilerStatsLPr(pw, packageName);
19042             }
19043
19044             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
19045                 if (dumpState.onTitlePrinted()) pw.println();
19046                 mSettings.dumpReadMessagesLPr(pw, dumpState);
19047
19048                 pw.println();
19049                 pw.println("Package warning messages:");
19050                 BufferedReader in = null;
19051                 String line = null;
19052                 try {
19053                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
19054                     while ((line = in.readLine()) != null) {
19055                         if (line.contains("ignored: updated version")) continue;
19056                         pw.println(line);
19057                     }
19058                 } catch (IOException ignored) {
19059                 } finally {
19060                     IoUtils.closeQuietly(in);
19061                 }
19062             }
19063
19064             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
19065                 BufferedReader in = null;
19066                 String line = null;
19067                 try {
19068                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
19069                     while ((line = in.readLine()) != null) {
19070                         if (line.contains("ignored: updated version")) continue;
19071                         pw.print("msg,");
19072                         pw.println(line);
19073                     }
19074                 } catch (IOException ignored) {
19075                 } finally {
19076                     IoUtils.closeQuietly(in);
19077                 }
19078             }
19079         }
19080     }
19081
19082     private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
19083         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
19084         ipw.println();
19085         ipw.println("Dexopt state:");
19086         ipw.increaseIndent();
19087         Collection<PackageParser.Package> packages = null;
19088         if (packageName != null) {
19089             PackageParser.Package targetPackage = mPackages.get(packageName);
19090             if (targetPackage != null) {
19091                 packages = Collections.singletonList(targetPackage);
19092             } else {
19093                 ipw.println("Unable to find package: " + packageName);
19094                 return;
19095             }
19096         } else {
19097             packages = mPackages.values();
19098         }
19099
19100         for (PackageParser.Package pkg : packages) {
19101             ipw.println("[" + pkg.packageName + "]");
19102             ipw.increaseIndent();
19103             mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
19104             ipw.decreaseIndent();
19105         }
19106     }
19107
19108     private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
19109         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
19110         ipw.println();
19111         ipw.println("Compiler stats:");
19112         ipw.increaseIndent();
19113         Collection<PackageParser.Package> packages = null;
19114         if (packageName != null) {
19115             PackageParser.Package targetPackage = mPackages.get(packageName);
19116             if (targetPackage != null) {
19117                 packages = Collections.singletonList(targetPackage);
19118             } else {
19119                 ipw.println("Unable to find package: " + packageName);
19120                 return;
19121             }
19122         } else {
19123             packages = mPackages.values();
19124         }
19125
19126         for (PackageParser.Package pkg : packages) {
19127             ipw.println("[" + pkg.packageName + "]");
19128             ipw.increaseIndent();
19129
19130             CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
19131             if (stats == null) {
19132                 ipw.println("(No recorded stats)");
19133             } else {
19134                 stats.dump(ipw);
19135             }
19136             ipw.decreaseIndent();
19137         }
19138     }
19139
19140     private String dumpDomainString(String packageName) {
19141         List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
19142                 .getList();
19143         List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
19144
19145         ArraySet<String> result = new ArraySet<>();
19146         if (iviList.size() > 0) {
19147             for (IntentFilterVerificationInfo ivi : iviList) {
19148                 for (String host : ivi.getDomains()) {
19149                     result.add(host);
19150                 }
19151             }
19152         }
19153         if (filters != null && filters.size() > 0) {
19154             for (IntentFilter filter : filters) {
19155                 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
19156                         && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
19157                                 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
19158                     result.addAll(filter.getHostsList());
19159                 }
19160             }
19161         }
19162
19163         StringBuilder sb = new StringBuilder(result.size() * 16);
19164         for (String domain : result) {
19165             if (sb.length() > 0) sb.append(" ");
19166             sb.append(domain);
19167         }
19168         return sb.toString();
19169     }
19170
19171     // ------- apps on sdcard specific code -------
19172     static final boolean DEBUG_SD_INSTALL = false;
19173
19174     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
19175
19176     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
19177
19178     private boolean mMediaMounted = false;
19179
19180     static String getEncryptKey() {
19181         try {
19182             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
19183                     SD_ENCRYPTION_KEYSTORE_NAME);
19184             if (sdEncKey == null) {
19185                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
19186                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
19187                 if (sdEncKey == null) {
19188                     Slog.e(TAG, "Failed to create encryption keys");
19189                     return null;
19190                 }
19191             }
19192             return sdEncKey;
19193         } catch (NoSuchAlgorithmException nsae) {
19194             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
19195             return null;
19196         } catch (IOException ioe) {
19197             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
19198             return null;
19199         }
19200     }
19201
19202     /*
19203      * Update media status on PackageManager.
19204      */
19205     @Override
19206     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
19207         int callingUid = Binder.getCallingUid();
19208         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
19209             throw new SecurityException("Media status can only be updated by the system");
19210         }
19211         // reader; this apparently protects mMediaMounted, but should probably
19212         // be a different lock in that case.
19213         synchronized (mPackages) {
19214             Log.i(TAG, "Updating external media status from "
19215                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
19216                     + (mediaStatus ? "mounted" : "unmounted"));
19217             if (DEBUG_SD_INSTALL)
19218                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
19219                         + ", mMediaMounted=" + mMediaMounted);
19220             if (mediaStatus == mMediaMounted) {
19221                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
19222                         : 0, -1);
19223                 mHandler.sendMessage(msg);
19224                 return;
19225             }
19226             mMediaMounted = mediaStatus;
19227         }
19228         // Queue up an async operation since the package installation may take a
19229         // little while.
19230         mHandler.post(new Runnable() {
19231             public void run() {
19232                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
19233             }
19234         });
19235     }
19236
19237     /**
19238      * Called by MountService when the initial ASECs to scan are available.
19239      * Should block until all the ASEC containers are finished being scanned.
19240      */
19241     public void scanAvailableAsecs() {
19242         updateExternalMediaStatusInner(true, false, false);
19243     }
19244
19245     /*
19246      * Collect information of applications on external media, map them against
19247      * existing containers and update information based on current mount status.
19248      * Please note that we always have to report status if reportStatus has been
19249      * set to true especially when unloading packages.
19250      */
19251     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
19252             boolean externalStorage) {
19253         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
19254         int[] uidArr = EmptyArray.INT;
19255
19256         final String[] list = PackageHelper.getSecureContainerList();
19257         if (ArrayUtils.isEmpty(list)) {
19258             Log.i(TAG, "No secure containers found");
19259         } else {
19260             // Process list of secure containers and categorize them
19261             // as active or stale based on their package internal state.
19262
19263             // reader
19264             synchronized (mPackages) {
19265                 for (String cid : list) {
19266                     // Leave stages untouched for now; installer service owns them
19267                     if (PackageInstallerService.isStageName(cid)) continue;
19268
19269                     if (DEBUG_SD_INSTALL)
19270                         Log.i(TAG, "Processing container " + cid);
19271                     String pkgName = getAsecPackageName(cid);
19272                     if (pkgName == null) {
19273                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
19274                         continue;
19275                     }
19276                     if (DEBUG_SD_INSTALL)
19277                         Log.i(TAG, "Looking for pkg : " + pkgName);
19278
19279                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
19280                     if (ps == null) {
19281                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
19282                         continue;
19283                     }
19284
19285                     /*
19286                      * Skip packages that are not external if we're unmounting
19287                      * external storage.
19288                      */
19289                     if (externalStorage && !isMounted && !isExternal(ps)) {
19290                         continue;
19291                     }
19292
19293                     final AsecInstallArgs args = new AsecInstallArgs(cid,
19294                             getAppDexInstructionSets(ps), ps.isForwardLocked());
19295                     // The package status is changed only if the code path
19296                     // matches between settings and the container id.
19297                     if (ps.codePathString != null
19298                             && ps.codePathString.startsWith(args.getCodePath())) {
19299                         if (DEBUG_SD_INSTALL) {
19300                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
19301                                     + " at code path: " + ps.codePathString);
19302                         }
19303
19304                         // We do have a valid package installed on sdcard
19305                         processCids.put(args, ps.codePathString);
19306                         final int uid = ps.appId;
19307                         if (uid != -1) {
19308                             uidArr = ArrayUtils.appendInt(uidArr, uid);
19309                         }
19310                     } else {
19311                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
19312                                 + ps.codePathString);
19313                     }
19314                 }
19315             }
19316
19317             Arrays.sort(uidArr);
19318         }
19319
19320         // Process packages with valid entries.
19321         if (isMounted) {
19322             if (DEBUG_SD_INSTALL)
19323                 Log.i(TAG, "Loading packages");
19324             loadMediaPackages(processCids, uidArr, externalStorage);
19325             startCleaningPackages();
19326             mInstallerService.onSecureContainersAvailable();
19327         } else {
19328             if (DEBUG_SD_INSTALL)
19329                 Log.i(TAG, "Unloading packages");
19330             unloadMediaPackages(processCids, uidArr, reportStatus);
19331         }
19332     }
19333
19334     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19335             ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
19336         final int size = infos.size();
19337         final String[] packageNames = new String[size];
19338         final int[] packageUids = new int[size];
19339         for (int i = 0; i < size; i++) {
19340             final ApplicationInfo info = infos.get(i);
19341             packageNames[i] = info.packageName;
19342             packageUids[i] = info.uid;
19343         }
19344         sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
19345                 finishedReceiver);
19346     }
19347
19348     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19349             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
19350         sendResourcesChangedBroadcast(mediaStatus, replacing,
19351                 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
19352     }
19353
19354     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19355             String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
19356         int size = pkgList.length;
19357         if (size > 0) {
19358             // Send broadcasts here
19359             Bundle extras = new Bundle();
19360             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
19361             if (uidArr != null) {
19362                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
19363             }
19364             if (replacing) {
19365                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
19366             }
19367             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
19368                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
19369             sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
19370         }
19371     }
19372
19373    /*
19374      * Look at potentially valid container ids from processCids If package
19375      * information doesn't match the one on record or package scanning fails,
19376      * the cid is added to list of removeCids. We currently don't delete stale
19377      * containers.
19378      */
19379     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
19380             boolean externalStorage) {
19381         ArrayList<String> pkgList = new ArrayList<String>();
19382         Set<AsecInstallArgs> keys = processCids.keySet();
19383
19384         for (AsecInstallArgs args : keys) {
19385             String codePath = processCids.get(args);
19386             if (DEBUG_SD_INSTALL)
19387                 Log.i(TAG, "Loading container : " + args.cid);
19388             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
19389             try {
19390                 // Make sure there are no container errors first.
19391                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
19392                     Slog.e(TAG, "Failed to mount cid : " + args.cid
19393                             + " when installing from sdcard");
19394                     continue;
19395                 }
19396                 // Check code path here.
19397                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
19398                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
19399                             + " does not match one in settings " + codePath);
19400                     continue;
19401                 }
19402                 // Parse package
19403                 int parseFlags = mDefParseFlags;
19404                 if (args.isExternalAsec()) {
19405                     parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
19406                 }
19407                 if (args.isFwdLocked()) {
19408                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
19409                 }
19410
19411                 synchronized (mInstallLock) {
19412                     PackageParser.Package pkg = null;
19413                     try {
19414                         // Sadly we don't know the package name yet to freeze it
19415                         pkg = scanPackageTracedLI(new File(codePath), parseFlags,
19416                                 SCAN_IGNORE_FROZEN, 0, null);
19417                     } catch (PackageManagerException e) {
19418                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
19419                     }
19420                     // Scan the package
19421                     if (pkg != null) {
19422                         /*
19423                          * TODO why is the lock being held? doPostInstall is
19424                          * called in other places without the lock. This needs
19425                          * to be straightened out.
19426                          */
19427                         // writer
19428                         synchronized (mPackages) {
19429                             retCode = PackageManager.INSTALL_SUCCEEDED;
19430                             pkgList.add(pkg.packageName);
19431                             // Post process args
19432                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
19433                                     pkg.applicationInfo.uid);
19434                         }
19435                     } else {
19436                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
19437                     }
19438                 }
19439
19440             } finally {
19441                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
19442                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
19443                 }
19444             }
19445         }
19446         // writer
19447         synchronized (mPackages) {
19448             // If the platform SDK has changed since the last time we booted,
19449             // we need to re-grant app permission to catch any new ones that
19450             // appear. This is really a hack, and means that apps can in some
19451             // cases get permissions that the user didn't initially explicitly
19452             // allow... it would be nice to have some better way to handle
19453             // this situation.
19454             final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
19455                     : mSettings.getInternalVersion();
19456             final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
19457                     : StorageManager.UUID_PRIVATE_INTERNAL;
19458
19459             int updateFlags = UPDATE_PERMISSIONS_ALL;
19460             if (ver.sdkVersion != mSdkVersion) {
19461                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19462                         + mSdkVersion + "; regranting permissions for external");
19463                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19464             }
19465             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19466
19467             // Yay, everything is now upgraded
19468             ver.forceCurrent();
19469
19470             // can downgrade to reader
19471             // Persist settings
19472             mSettings.writeLPr();
19473         }
19474         // Send a broadcast to let everyone know we are done processing
19475         if (pkgList.size() > 0) {
19476             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
19477         }
19478     }
19479
19480    /*
19481      * Utility method to unload a list of specified containers
19482      */
19483     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
19484         // Just unmount all valid containers.
19485         for (AsecInstallArgs arg : cidArgs) {
19486             synchronized (mInstallLock) {
19487                 arg.doPostDeleteLI(false);
19488            }
19489        }
19490    }
19491
19492     /*
19493      * Unload packages mounted on external media. This involves deleting package
19494      * data from internal structures, sending broadcasts about disabled packages,
19495      * gc'ing to free up references, unmounting all secure containers
19496      * corresponding to packages on external media, and posting a
19497      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
19498      * that we always have to post this message if status has been requested no
19499      * matter what.
19500      */
19501     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
19502             final boolean reportStatus) {
19503         if (DEBUG_SD_INSTALL)
19504             Log.i(TAG, "unloading media packages");
19505         ArrayList<String> pkgList = new ArrayList<String>();
19506         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
19507         final Set<AsecInstallArgs> keys = processCids.keySet();
19508         for (AsecInstallArgs args : keys) {
19509             String pkgName = args.getPackageName();
19510             if (DEBUG_SD_INSTALL)
19511                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
19512             // Delete package internally
19513             PackageRemovedInfo outInfo = new PackageRemovedInfo();
19514             synchronized (mInstallLock) {
19515                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19516                 final boolean res;
19517                 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
19518                         "unloadMediaPackages")) {
19519                     res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
19520                             null);
19521                 }
19522                 if (res) {
19523                     pkgList.add(pkgName);
19524                 } else {
19525                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
19526                     failedList.add(args);
19527                 }
19528             }
19529         }
19530
19531         // reader
19532         synchronized (mPackages) {
19533             // We didn't update the settings after removing each package;
19534             // write them now for all packages.
19535             mSettings.writeLPr();
19536         }
19537
19538         // We have to absolutely send UPDATED_MEDIA_STATUS only
19539         // after confirming that all the receivers processed the ordered
19540         // broadcast when packages get disabled, force a gc to clean things up.
19541         // and unload all the containers.
19542         if (pkgList.size() > 0) {
19543             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
19544                     new IIntentReceiver.Stub() {
19545                 public void performReceive(Intent intent, int resultCode, String data,
19546                         Bundle extras, boolean ordered, boolean sticky,
19547                         int sendingUser) throws RemoteException {
19548                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
19549                             reportStatus ? 1 : 0, 1, keys);
19550                     mHandler.sendMessage(msg);
19551                 }
19552             });
19553         } else {
19554             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
19555                     keys);
19556             mHandler.sendMessage(msg);
19557         }
19558     }
19559
19560     private void loadPrivatePackages(final VolumeInfo vol) {
19561         mHandler.post(new Runnable() {
19562             @Override
19563             public void run() {
19564                 loadPrivatePackagesInner(vol);
19565             }
19566         });
19567     }
19568
19569     private void loadPrivatePackagesInner(VolumeInfo vol) {
19570         final String volumeUuid = vol.fsUuid;
19571         if (TextUtils.isEmpty(volumeUuid)) {
19572             Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
19573             return;
19574         }
19575
19576         final ArrayList<PackageFreezer> freezers = new ArrayList<>();
19577         final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
19578         final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
19579
19580         final VersionInfo ver;
19581         final List<PackageSetting> packages;
19582         synchronized (mPackages) {
19583             ver = mSettings.findOrCreateVersion(volumeUuid);
19584             packages = mSettings.getVolumePackagesLPr(volumeUuid);
19585         }
19586
19587         for (PackageSetting ps : packages) {
19588             freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
19589             synchronized (mInstallLock) {
19590                 final PackageParser.Package pkg;
19591                 try {
19592                     pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
19593                     loaded.add(pkg.applicationInfo);
19594
19595                 } catch (PackageManagerException e) {
19596                     Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
19597                 }
19598
19599                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
19600                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
19601                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
19602                                     | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19603                 }
19604             }
19605         }
19606
19607         // Reconcile app data for all started/unlocked users
19608         final StorageManager sm = mContext.getSystemService(StorageManager.class);
19609         final UserManager um = mContext.getSystemService(UserManager.class);
19610         UserManagerInternal umInternal = getUserManagerInternal();
19611         for (UserInfo user : um.getUsers()) {
19612             final int flags;
19613             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
19614                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19615             } else if (umInternal.isUserRunning(user.id)) {
19616                 flags = StorageManager.FLAG_STORAGE_DE;
19617             } else {
19618                 continue;
19619             }
19620
19621             try {
19622                 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
19623                 synchronized (mInstallLock) {
19624                     reconcileAppsDataLI(volumeUuid, user.id, flags);
19625                 }
19626             } catch (IllegalStateException e) {
19627                 // Device was probably ejected, and we'll process that event momentarily
19628                 Slog.w(TAG, "Failed to prepare storage: " + e);
19629             }
19630         }
19631
19632         synchronized (mPackages) {
19633             int updateFlags = UPDATE_PERMISSIONS_ALL;
19634             if (ver.sdkVersion != mSdkVersion) {
19635                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19636                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
19637                 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19638             }
19639             updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19640
19641             // Yay, everything is now upgraded
19642             ver.forceCurrent();
19643
19644             mSettings.writeLPr();
19645         }
19646
19647         for (PackageFreezer freezer : freezers) {
19648             freezer.close();
19649         }
19650
19651         if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
19652         sendResourcesChangedBroadcast(true, false, loaded, null);
19653     }
19654
19655     private void unloadPrivatePackages(final VolumeInfo vol) {
19656         mHandler.post(new Runnable() {
19657             @Override
19658             public void run() {
19659                 unloadPrivatePackagesInner(vol);
19660             }
19661         });
19662     }
19663
19664     private void unloadPrivatePackagesInner(VolumeInfo vol) {
19665         final String volumeUuid = vol.fsUuid;
19666         if (TextUtils.isEmpty(volumeUuid)) {
19667             Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
19668             return;
19669         }
19670
19671         final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
19672         synchronized (mInstallLock) {
19673         synchronized (mPackages) {
19674             final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
19675             for (PackageSetting ps : packages) {
19676                 if (ps.pkg == null) continue;
19677
19678                 final ApplicationInfo info = ps.pkg.applicationInfo;
19679                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19680                 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
19681
19682                 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
19683                         "unloadPrivatePackagesInner")) {
19684                     if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
19685                             false, null)) {
19686                         unloaded.add(info);
19687                     } else {
19688                         Slog.w(TAG, "Failed to unload " + ps.codePath);
19689                     }
19690                 }
19691
19692                 // Try very hard to release any references to this package
19693                 // so we don't risk the system server being killed due to
19694                 // open FDs
19695                 AttributeCache.instance().removePackage(ps.name);
19696             }
19697
19698             mSettings.writeLPr();
19699         }
19700         }
19701
19702         if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
19703         sendResourcesChangedBroadcast(false, false, unloaded, null);
19704
19705         // Try very hard to release any references to this path so we don't risk
19706         // the system server being killed due to open FDs
19707         ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
19708
19709         for (int i = 0; i < 3; i++) {
19710             System.gc();
19711             System.runFinalization();
19712         }
19713     }
19714
19715     /**
19716      * Prepare storage areas for given user on all mounted devices.
19717      */
19718     void prepareUserData(int userId, int userSerial, int flags) {
19719         synchronized (mInstallLock) {
19720             final StorageManager storage = mContext.getSystemService(StorageManager.class);
19721             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19722                 final String volumeUuid = vol.getFsUuid();
19723                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
19724             }
19725         }
19726     }
19727
19728     private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags,
19729             boolean allowRecover) {
19730         // Prepare storage and verify that serial numbers are consistent; if
19731         // there's a mismatch we need to destroy to avoid leaking data
19732         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19733         try {
19734             storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
19735
19736             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
19737                 UserManagerService.enforceSerialNumber(
19738                         Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
19739                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19740                     UserManagerService.enforceSerialNumber(
19741                             Environment.getDataSystemDeDirectory(userId), userSerial);
19742                 }
19743             }
19744             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
19745                 UserManagerService.enforceSerialNumber(
19746                         Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
19747                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19748                     UserManagerService.enforceSerialNumber(
19749                             Environment.getDataSystemCeDirectory(userId), userSerial);
19750                 }
19751             }
19752
19753             synchronized (mInstallLock) {
19754                 mInstaller.createUserData(volumeUuid, userId, userSerial, flags);
19755             }
19756         } catch (Exception e) {
19757             logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid
19758                     + " because we failed to prepare: " + e);
19759             destroyUserDataLI(volumeUuid, userId,
19760                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19761
19762             if (allowRecover) {
19763                 // Try one last time; if we fail again we're really in trouble
19764                 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false);
19765             }
19766         }
19767     }
19768
19769     /**
19770      * Destroy storage areas for given user on all mounted devices.
19771      */
19772     void destroyUserData(int userId, int flags) {
19773         synchronized (mInstallLock) {
19774             final StorageManager storage = mContext.getSystemService(StorageManager.class);
19775             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19776                 final String volumeUuid = vol.getFsUuid();
19777                 destroyUserDataLI(volumeUuid, userId, flags);
19778             }
19779         }
19780     }
19781
19782     private void destroyUserDataLI(String volumeUuid, int userId, int flags) {
19783         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19784         try {
19785             // Clean up app data, profile data, and media data
19786             mInstaller.destroyUserData(volumeUuid, userId, flags);
19787
19788             // Clean up system data
19789             if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19790                 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19791                     FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
19792                     FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
19793                 }
19794                 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19795                     FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
19796                 }
19797             }
19798
19799             // Data with special labels is now gone, so finish the job
19800             storage.destroyUserStorage(volumeUuid, userId, flags);
19801
19802         } catch (Exception e) {
19803             logCriticalInfo(Log.WARN,
19804                     "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e);
19805         }
19806     }
19807
19808     /**
19809      * Examine all users present on given mounted volume, and destroy data
19810      * belonging to users that are no longer valid, or whose user ID has been
19811      * recycled.
19812      */
19813     private void reconcileUsers(String volumeUuid) {
19814         final List<File> files = new ArrayList<>();
19815         Collections.addAll(files, FileUtils
19816                 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
19817         Collections.addAll(files, FileUtils
19818                 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
19819         Collections.addAll(files, FileUtils
19820                 .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
19821         Collections.addAll(files, FileUtils
19822                 .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
19823         for (File file : files) {
19824             if (!file.isDirectory()) continue;
19825
19826             final int userId;
19827             final UserInfo info;
19828             try {
19829                 userId = Integer.parseInt(file.getName());
19830                 info = sUserManager.getUserInfo(userId);
19831             } catch (NumberFormatException e) {
19832                 Slog.w(TAG, "Invalid user directory " + file);
19833                 continue;
19834             }
19835
19836             boolean destroyUser = false;
19837             if (info == null) {
19838                 logCriticalInfo(Log.WARN, "Destroying user directory " + file
19839                         + " because no matching user was found");
19840                 destroyUser = true;
19841             } else if (!mOnlyCore) {
19842                 try {
19843                     UserManagerService.enforceSerialNumber(file, info.serialNumber);
19844                 } catch (IOException e) {
19845                     logCriticalInfo(Log.WARN, "Destroying user directory " + file
19846                             + " because we failed to enforce serial number: " + e);
19847                     destroyUser = true;
19848                 }
19849             }
19850
19851             if (destroyUser) {
19852                 synchronized (mInstallLock) {
19853                     destroyUserDataLI(volumeUuid, userId,
19854                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19855                 }
19856             }
19857         }
19858     }
19859
19860     private void assertPackageKnown(String volumeUuid, String packageName)
19861             throws PackageManagerException {
19862         synchronized (mPackages) {
19863             // Normalize package name to handle renamed packages
19864             packageName = normalizePackageNameLPr(packageName);
19865
19866             final PackageSetting ps = mSettings.mPackages.get(packageName);
19867             if (ps == null) {
19868                 throw new PackageManagerException("Package " + packageName + " is unknown");
19869             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19870                 throw new PackageManagerException(
19871                         "Package " + packageName + " found on unknown volume " + volumeUuid
19872                                 + "; expected volume " + ps.volumeUuid);
19873             }
19874         }
19875     }
19876
19877     private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
19878             throws PackageManagerException {
19879         synchronized (mPackages) {
19880             // Normalize package name to handle renamed packages
19881             packageName = normalizePackageNameLPr(packageName);
19882
19883             final PackageSetting ps = mSettings.mPackages.get(packageName);
19884             if (ps == null) {
19885                 throw new PackageManagerException("Package " + packageName + " is unknown");
19886             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19887                 throw new PackageManagerException(
19888                         "Package " + packageName + " found on unknown volume " + volumeUuid
19889                                 + "; expected volume " + ps.volumeUuid);
19890             } else if (!ps.getInstalled(userId)) {
19891                 throw new PackageManagerException(
19892                         "Package " + packageName + " not installed for user " + userId);
19893             }
19894         }
19895     }
19896
19897     /**
19898      * Examine all apps present on given mounted volume, and destroy apps that
19899      * aren't expected, either due to uninstallation or reinstallation on
19900      * another volume.
19901      */
19902     private void reconcileApps(String volumeUuid) {
19903         final File[] files = FileUtils
19904                 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
19905         for (File file : files) {
19906             final boolean isPackage = (isApkFile(file) || file.isDirectory())
19907                     && !PackageInstallerService.isStageName(file.getName());
19908             if (!isPackage) {
19909                 // Ignore entries which are not packages
19910                 continue;
19911             }
19912
19913             try {
19914                 final PackageLite pkg = PackageParser.parsePackageLite(file,
19915                         PackageParser.PARSE_MUST_BE_APK);
19916                 assertPackageKnown(volumeUuid, pkg.packageName);
19917
19918             } catch (PackageParserException | PackageManagerException e) {
19919                 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19920                 synchronized (mInstallLock) {
19921                     removeCodePathLI(file);
19922                 }
19923             }
19924         }
19925     }
19926
19927     /**
19928      * Reconcile all app data for the given user.
19929      * <p>
19930      * Verifies that directories exist and that ownership and labeling is
19931      * correct for all installed apps on all mounted volumes.
19932      */
19933     void reconcileAppsData(int userId, int flags) {
19934         final StorageManager storage = mContext.getSystemService(StorageManager.class);
19935         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19936             final String volumeUuid = vol.getFsUuid();
19937             synchronized (mInstallLock) {
19938                 reconcileAppsDataLI(volumeUuid, userId, flags);
19939             }
19940         }
19941     }
19942
19943     /**
19944      * Reconcile all app data on given mounted volume.
19945      * <p>
19946      * Destroys app data that isn't expected, either due to uninstallation or
19947      * reinstallation on another volume.
19948      * <p>
19949      * Verifies that directories exist and that ownership and labeling is
19950      * correct for all installed apps.
19951      */
19952     private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) {
19953         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
19954                 + Integer.toHexString(flags));
19955
19956         final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
19957         final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
19958
19959         // First look for stale data that doesn't belong, and check if things
19960         // have changed since we did our last restorecon
19961         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19962             if (StorageManager.isFileEncryptedNativeOrEmulated()
19963                     && !StorageManager.isUserKeyUnlocked(userId)) {
19964                 throw new RuntimeException(
19965                         "Yikes, someone asked us to reconcile CE storage while " + userId
19966                                 + " was still locked; this would have caused massive data loss!");
19967             }
19968
19969             final File[] files = FileUtils.listFilesOrEmpty(ceDir);
19970             for (File file : files) {
19971                 final String packageName = file.getName();
19972                 try {
19973                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
19974                 } catch (PackageManagerException e) {
19975                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19976                     try {
19977                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
19978                                 StorageManager.FLAG_STORAGE_CE, 0);
19979                     } catch (InstallerException e2) {
19980                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
19981                     }
19982                 }
19983             }
19984         }
19985         if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19986             final File[] files = FileUtils.listFilesOrEmpty(deDir);
19987             for (File file : files) {
19988                 final String packageName = file.getName();
19989                 try {
19990                     assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
19991                 } catch (PackageManagerException e) {
19992                     logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19993                     try {
19994                         mInstaller.destroyAppData(volumeUuid, packageName, userId,
19995                                 StorageManager.FLAG_STORAGE_DE, 0);
19996                     } catch (InstallerException e2) {
19997                         logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
19998                     }
19999                 }
20000             }
20001         }
20002
20003         // Ensure that data directories are ready to roll for all packages
20004         // installed for this volume and user
20005         final List<PackageSetting> packages;
20006         synchronized (mPackages) {
20007             packages = mSettings.getVolumePackagesLPr(volumeUuid);
20008         }
20009         int preparedCount = 0;
20010         for (PackageSetting ps : packages) {
20011             final String packageName = ps.name;
20012             if (ps.pkg == null) {
20013                 Slog.w(TAG, "Odd, missing scanned package " + packageName);
20014                 // TODO: might be due to legacy ASEC apps; we should circle back
20015                 // and reconcile again once they're scanned
20016                 continue;
20017             }
20018
20019             if (ps.getInstalled(userId)) {
20020                 prepareAppDataLIF(ps.pkg, userId, flags);
20021
20022                 if (maybeMigrateAppDataLIF(ps.pkg, userId)) {
20023                     // We may have just shuffled around app data directories, so
20024                     // prepare them one more time
20025                     prepareAppDataLIF(ps.pkg, userId, flags);
20026                 }
20027
20028                 preparedCount++;
20029             }
20030         }
20031
20032         Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
20033     }
20034
20035     /**
20036      * Prepare app data for the given app just after it was installed or
20037      * upgraded. This method carefully only touches users that it's installed
20038      * for, and it forces a restorecon to handle any seinfo changes.
20039      * <p>
20040      * Verifies that directories exist and that ownership and labeling is
20041      * correct for all installed apps. If there is an ownership mismatch, it
20042      * will try recovering system apps by wiping data; third-party app data is
20043      * left intact.
20044      * <p>
20045      * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
20046      */
20047     private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
20048         final PackageSetting ps;
20049         synchronized (mPackages) {
20050             ps = mSettings.mPackages.get(pkg.packageName);
20051             mSettings.writeKernelMappingLPr(ps);
20052         }
20053
20054         final UserManager um = mContext.getSystemService(UserManager.class);
20055         UserManagerInternal umInternal = getUserManagerInternal();
20056         for (UserInfo user : um.getUsers()) {
20057             final int flags;
20058             if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
20059                 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20060             } else if (umInternal.isUserRunning(user.id)) {
20061                 flags = StorageManager.FLAG_STORAGE_DE;
20062             } else {
20063                 continue;
20064             }
20065
20066             if (ps.getInstalled(user.id)) {
20067                 // TODO: when user data is locked, mark that we're still dirty
20068                 prepareAppDataLIF(pkg, user.id, flags);
20069             }
20070         }
20071     }
20072
20073     /**
20074      * Prepare app data for the given app.
20075      * <p>
20076      * Verifies that directories exist and that ownership and labeling is
20077      * correct for all installed apps. If there is an ownership mismatch, this
20078      * will try recovering system apps by wiping data; third-party app data is
20079      * left intact.
20080      */
20081     private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
20082         if (pkg == null) {
20083             Slog.wtf(TAG, "Package was null!", new Throwable());
20084             return;
20085         }
20086         prepareAppDataLeafLIF(pkg, userId, flags);
20087         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
20088         for (int i = 0; i < childCount; i++) {
20089             prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
20090         }
20091     }
20092
20093     private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
20094         if (DEBUG_APP_DATA) {
20095             Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
20096                     + Integer.toHexString(flags));
20097         }
20098
20099         final String volumeUuid = pkg.volumeUuid;
20100         final String packageName = pkg.packageName;
20101         final ApplicationInfo app = pkg.applicationInfo;
20102         final int appId = UserHandle.getAppId(app.uid);
20103
20104         Preconditions.checkNotNull(app.seinfo);
20105
20106         try {
20107             mInstaller.createAppData(volumeUuid, packageName, userId, flags,
20108                     appId, app.seinfo, app.targetSdkVersion);
20109         } catch (InstallerException e) {
20110             if (app.isSystemApp()) {
20111                 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
20112                         + ", but trying to recover: " + e);
20113                 destroyAppDataLeafLIF(pkg, userId, flags);
20114                 try {
20115                     mInstaller.createAppData(volumeUuid, packageName, userId, flags,
20116                             appId, app.seinfo, app.targetSdkVersion);
20117                     logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
20118                 } catch (InstallerException e2) {
20119                     logCriticalInfo(Log.DEBUG, "Recovery failed!");
20120                 }
20121             } else {
20122                 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
20123             }
20124         }
20125
20126         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
20127             try {
20128                 // CE storage is unlocked right now, so read out the inode and
20129                 // remember for use later when it's locked
20130                 // TODO: mark this structure as dirty so we persist it!
20131                 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId,
20132                         StorageManager.FLAG_STORAGE_CE);
20133                 synchronized (mPackages) {
20134                     final PackageSetting ps = mSettings.mPackages.get(packageName);
20135                     if (ps != null) {
20136                         ps.setCeDataInode(ceDataInode, userId);
20137                     }
20138                 }
20139             } catch (InstallerException e) {
20140                 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e);
20141             }
20142         }
20143
20144         prepareAppDataContentsLeafLIF(pkg, userId, flags);
20145     }
20146
20147     private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
20148         if (pkg == null) {
20149             Slog.wtf(TAG, "Package was null!", new Throwable());
20150             return;
20151         }
20152         prepareAppDataContentsLeafLIF(pkg, userId, flags);
20153         final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
20154         for (int i = 0; i < childCount; i++) {
20155             prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
20156         }
20157     }
20158
20159     private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
20160         final String volumeUuid = pkg.volumeUuid;
20161         final String packageName = pkg.packageName;
20162         final ApplicationInfo app = pkg.applicationInfo;
20163
20164         if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
20165             // Create a native library symlink only if we have native libraries
20166             // and if the native libraries are 32 bit libraries. We do not provide
20167             // this symlink for 64 bit libraries.
20168             if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
20169                 final String nativeLibPath = app.nativeLibraryDir;
20170                 try {
20171                     mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
20172                             nativeLibPath, userId);
20173                 } catch (InstallerException e) {
20174                     Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
20175                 }
20176             }
20177         }
20178     }
20179
20180     /**
20181      * For system apps on non-FBE devices, this method migrates any existing
20182      * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
20183      * requested by the app.
20184      */
20185     private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
20186         if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
20187                 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
20188             final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
20189                     ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
20190             try {
20191                 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
20192                         storageTarget);
20193             } catch (InstallerException e) {
20194                 logCriticalInfo(Log.WARN,
20195                         "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
20196             }
20197             return true;
20198         } else {
20199             return false;
20200         }
20201     }
20202
20203     public PackageFreezer freezePackage(String packageName, String killReason) {
20204         return freezePackage(packageName, UserHandle.USER_ALL, killReason);
20205     }
20206
20207     public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
20208         return new PackageFreezer(packageName, userId, killReason);
20209     }
20210
20211     public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
20212             String killReason) {
20213         return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
20214     }
20215
20216     public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
20217             String killReason) {
20218         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
20219             return new PackageFreezer();
20220         } else {
20221             return freezePackage(packageName, userId, killReason);
20222         }
20223     }
20224
20225     public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
20226             String killReason) {
20227         return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
20228     }
20229
20230     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
20231             String killReason) {
20232         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
20233             return new PackageFreezer();
20234         } else {
20235             return freezePackage(packageName, userId, killReason);
20236         }
20237     }
20238
20239     /**
20240      * Class that freezes and kills the given package upon creation, and
20241      * unfreezes it upon closing. This is typically used when doing surgery on
20242      * app code/data to prevent the app from running while you're working.
20243      */
20244     private class PackageFreezer implements AutoCloseable {
20245         private final String mPackageName;
20246         private final PackageFreezer[] mChildren;
20247
20248         private final boolean mWeFroze;
20249
20250         private final AtomicBoolean mClosed = new AtomicBoolean();
20251         private final CloseGuard mCloseGuard = CloseGuard.get();
20252
20253         /**
20254          * Create and return a stub freezer that doesn't actually do anything,
20255          * typically used when someone requested
20256          * {@link PackageManager#INSTALL_DONT_KILL_APP} or
20257          * {@link PackageManager#DELETE_DONT_KILL_APP}.
20258          */
20259         public PackageFreezer() {
20260             mPackageName = null;
20261             mChildren = null;
20262             mWeFroze = false;
20263             mCloseGuard.open("close");
20264         }
20265
20266         public PackageFreezer(String packageName, int userId, String killReason) {
20267             synchronized (mPackages) {
20268                 mPackageName = packageName;
20269                 mWeFroze = mFrozenPackages.add(mPackageName);
20270
20271                 final PackageSetting ps = mSettings.mPackages.get(mPackageName);
20272                 if (ps != null) {
20273                     killApplication(ps.name, ps.appId, userId, killReason);
20274                 }
20275
20276                 final PackageParser.Package p = mPackages.get(packageName);
20277                 if (p != null && p.childPackages != null) {
20278                     final int N = p.childPackages.size();
20279                     mChildren = new PackageFreezer[N];
20280                     for (int i = 0; i < N; i++) {
20281                         mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
20282                                 userId, killReason);
20283                     }
20284                 } else {
20285                     mChildren = null;
20286                 }
20287             }
20288             mCloseGuard.open("close");
20289         }
20290
20291         @Override
20292         protected void finalize() throws Throwable {
20293             try {
20294                 mCloseGuard.warnIfOpen();
20295                 close();
20296             } finally {
20297                 super.finalize();
20298             }
20299         }
20300
20301         @Override
20302         public void close() {
20303             mCloseGuard.close();
20304             if (mClosed.compareAndSet(false, true)) {
20305                 synchronized (mPackages) {
20306                     if (mWeFroze) {
20307                         mFrozenPackages.remove(mPackageName);
20308                     }
20309
20310                     if (mChildren != null) {
20311                         for (PackageFreezer freezer : mChildren) {
20312                             freezer.close();
20313                         }
20314                     }
20315                 }
20316             }
20317         }
20318     }
20319
20320     /**
20321      * Verify that given package is currently frozen.
20322      */
20323     private void checkPackageFrozen(String packageName) {
20324         synchronized (mPackages) {
20325             if (!mFrozenPackages.contains(packageName)) {
20326                 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
20327             }
20328         }
20329     }
20330
20331     @Override
20332     public int movePackage(final String packageName, final String volumeUuid) {
20333         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
20334
20335         final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
20336         final int moveId = mNextMoveId.getAndIncrement();
20337         mHandler.post(new Runnable() {
20338             @Override
20339             public void run() {
20340                 try {
20341                     movePackageInternal(packageName, volumeUuid, moveId, user);
20342                 } catch (PackageManagerException e) {
20343                     Slog.w(TAG, "Failed to move " + packageName, e);
20344                     mMoveCallbacks.notifyStatusChanged(moveId,
20345                             PackageManager.MOVE_FAILED_INTERNAL_ERROR);
20346                 }
20347             }
20348         });
20349         return moveId;
20350     }
20351
20352     private void movePackageInternal(final String packageName, final String volumeUuid,
20353             final int moveId, UserHandle user) throws PackageManagerException {
20354         final StorageManager storage = mContext.getSystemService(StorageManager.class);
20355         final PackageManager pm = mContext.getPackageManager();
20356
20357         final boolean currentAsec;
20358         final String currentVolumeUuid;
20359         final File codeFile;
20360         final String installerPackageName;
20361         final String packageAbiOverride;
20362         final int appId;
20363         final String seinfo;
20364         final String label;
20365         final int targetSdkVersion;
20366         final PackageFreezer freezer;
20367         final int[] installedUserIds;
20368
20369         // reader
20370         synchronized (mPackages) {
20371             final PackageParser.Package pkg = mPackages.get(packageName);
20372             final PackageSetting ps = mSettings.mPackages.get(packageName);
20373             if (pkg == null || ps == null) {
20374                 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
20375             }
20376
20377             if (pkg.applicationInfo.isSystemApp()) {
20378                 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
20379                         "Cannot move system application");
20380             }
20381
20382             if (pkg.applicationInfo.isExternalAsec()) {
20383                 currentAsec = true;
20384                 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
20385             } else if (pkg.applicationInfo.isForwardLocked()) {
20386                 currentAsec = true;
20387                 currentVolumeUuid = "forward_locked";
20388             } else {
20389                 currentAsec = false;
20390                 currentVolumeUuid = ps.volumeUuid;
20391
20392                 final File probe = new File(pkg.codePath);
20393                 final File probeOat = new File(probe, "oat");
20394                 if (!probe.isDirectory() || !probeOat.isDirectory()) {
20395                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20396                             "Move only supported for modern cluster style installs");
20397                 }
20398             }
20399
20400             if (Objects.equals(currentVolumeUuid, volumeUuid)) {
20401                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20402                         "Package already moved to " + volumeUuid);
20403             }
20404             if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
20405                 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
20406                         "Device admin cannot be moved");
20407             }
20408
20409             if (mFrozenPackages.contains(packageName)) {
20410                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
20411                         "Failed to move already frozen package");
20412             }
20413
20414             codeFile = new File(pkg.codePath);
20415             installerPackageName = ps.installerPackageName;
20416             packageAbiOverride = ps.cpuAbiOverrideString;
20417             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20418             seinfo = pkg.applicationInfo.seinfo;
20419             label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
20420             targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
20421             freezer = freezePackage(packageName, "movePackageInternal");
20422             installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
20423         }
20424
20425         final Bundle extras = new Bundle();
20426         extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
20427         extras.putString(Intent.EXTRA_TITLE, label);
20428         mMoveCallbacks.notifyCreated(moveId, extras);
20429
20430         int installFlags;
20431         final boolean moveCompleteApp;
20432         final File measurePath;
20433
20434         if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
20435             installFlags = INSTALL_INTERNAL;
20436             moveCompleteApp = !currentAsec;
20437             measurePath = Environment.getDataAppDirectory(volumeUuid);
20438         } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
20439             installFlags = INSTALL_EXTERNAL;
20440             moveCompleteApp = false;
20441             measurePath = storage.getPrimaryPhysicalVolume().getPath();
20442         } else {
20443             final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
20444             if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
20445                     || !volume.isMountedWritable()) {
20446                 freezer.close();
20447                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20448                         "Move location not mounted private volume");
20449             }
20450
20451             Preconditions.checkState(!currentAsec);
20452
20453             installFlags = INSTALL_INTERNAL;
20454             moveCompleteApp = true;
20455             measurePath = Environment.getDataAppDirectory(volumeUuid);
20456         }
20457
20458         final PackageStats stats = new PackageStats(null, -1);
20459         synchronized (mInstaller) {
20460             for (int userId : installedUserIds) {
20461                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
20462                     freezer.close();
20463                     throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20464                             "Failed to measure package size");
20465                 }
20466             }
20467         }
20468
20469         if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
20470                 + stats.dataSize);
20471
20472         final long startFreeBytes = measurePath.getFreeSpace();
20473         final long sizeBytes;
20474         if (moveCompleteApp) {
20475             sizeBytes = stats.codeSize + stats.dataSize;
20476         } else {
20477             sizeBytes = stats.codeSize;
20478         }
20479
20480         if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
20481             freezer.close();
20482             throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20483                     "Not enough free space to move");
20484         }
20485
20486         mMoveCallbacks.notifyStatusChanged(moveId, 10);
20487
20488         final CountDownLatch installedLatch = new CountDownLatch(1);
20489         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
20490             @Override
20491             public void onUserActionRequired(Intent intent) throws RemoteException {
20492                 throw new IllegalStateException();
20493             }
20494
20495             @Override
20496             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
20497                     Bundle extras) throws RemoteException {
20498                 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
20499                         + PackageManager.installStatusToString(returnCode, msg));
20500
20501                 installedLatch.countDown();
20502                 freezer.close();
20503
20504                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
20505                 switch (status) {
20506                     case PackageInstaller.STATUS_SUCCESS:
20507                         mMoveCallbacks.notifyStatusChanged(moveId,
20508                                 PackageManager.MOVE_SUCCEEDED);
20509                         break;
20510                     case PackageInstaller.STATUS_FAILURE_STORAGE:
20511                         mMoveCallbacks.notifyStatusChanged(moveId,
20512                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
20513                         break;
20514                     default:
20515                         mMoveCallbacks.notifyStatusChanged(moveId,
20516                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
20517                         break;
20518                 }
20519             }
20520         };
20521
20522         final MoveInfo move;
20523         if (moveCompleteApp) {
20524             // Kick off a thread to report progress estimates
20525             new Thread() {
20526                 @Override
20527                 public void run() {
20528                     while (true) {
20529                         try {
20530                             if (installedLatch.await(1, TimeUnit.SECONDS)) {
20531                                 break;
20532                             }
20533                         } catch (InterruptedException ignored) {
20534                         }
20535
20536                         final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
20537                         final int progress = 10 + (int) MathUtils.constrain(
20538                                 ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
20539                         mMoveCallbacks.notifyStatusChanged(moveId, progress);
20540                     }
20541                 }
20542             }.start();
20543
20544             final String dataAppName = codeFile.getName();
20545             move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
20546                     dataAppName, appId, seinfo, targetSdkVersion);
20547         } else {
20548             move = null;
20549         }
20550
20551         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
20552
20553         final Message msg = mHandler.obtainMessage(INIT_COPY);
20554         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
20555         final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
20556                 installerPackageName, volumeUuid, null /*verificationInfo*/, user,
20557                 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/);
20558         params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
20559         msg.obj = params;
20560
20561         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
20562                 System.identityHashCode(msg.obj));
20563         Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
20564                 System.identityHashCode(msg.obj));
20565
20566         mHandler.sendMessage(msg);
20567     }
20568
20569     @Override
20570     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
20571         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
20572
20573         final int realMoveId = mNextMoveId.getAndIncrement();
20574         final Bundle extras = new Bundle();
20575         extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
20576         mMoveCallbacks.notifyCreated(realMoveId, extras);
20577
20578         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
20579             @Override
20580             public void onCreated(int moveId, Bundle extras) {
20581                 // Ignored
20582             }
20583
20584             @Override
20585             public void onStatusChanged(int moveId, int status, long estMillis) {
20586                 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
20587             }
20588         };
20589
20590         final StorageManager storage = mContext.getSystemService(StorageManager.class);
20591         storage.setPrimaryStorageUuid(volumeUuid, callback);
20592         return realMoveId;
20593     }
20594
20595     @Override
20596     public int getMoveStatus(int moveId) {
20597         mContext.enforceCallingOrSelfPermission(
20598                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20599         return mMoveCallbacks.mLastStatus.get(moveId);
20600     }
20601
20602     @Override
20603     public void registerMoveCallback(IPackageMoveObserver callback) {
20604         mContext.enforceCallingOrSelfPermission(
20605                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20606         mMoveCallbacks.register(callback);
20607     }
20608
20609     @Override
20610     public void unregisterMoveCallback(IPackageMoveObserver callback) {
20611         mContext.enforceCallingOrSelfPermission(
20612                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20613         mMoveCallbacks.unregister(callback);
20614     }
20615
20616     @Override
20617     public boolean setInstallLocation(int loc) {
20618         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
20619                 null);
20620         if (getInstallLocation() == loc) {
20621             return true;
20622         }
20623         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
20624                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
20625             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
20626                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
20627             return true;
20628         }
20629         return false;
20630    }
20631
20632     @Override
20633     public int getInstallLocation() {
20634         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
20635                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
20636                 PackageHelper.APP_INSTALL_AUTO);
20637     }
20638
20639     /** Called by UserManagerService */
20640     void cleanUpUser(UserManagerService userManager, int userHandle) {
20641         synchronized (mPackages) {
20642             mDirtyUsers.remove(userHandle);
20643             mUserNeedsBadging.delete(userHandle);
20644             mSettings.removeUserLPw(userHandle);
20645             mPendingBroadcasts.remove(userHandle);
20646             mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
20647             removeUnusedPackagesLPw(userManager, userHandle);
20648         }
20649     }
20650
20651     /**
20652      * We're removing userHandle and would like to remove any downloaded packages
20653      * that are no longer in use by any other user.
20654      * @param userHandle the user being removed
20655      */
20656     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
20657         final boolean DEBUG_CLEAN_APKS = false;
20658         int [] users = userManager.getUserIds();
20659         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
20660         while (psit.hasNext()) {
20661             PackageSetting ps = psit.next();
20662             if (ps.pkg == null) {
20663                 continue;
20664             }
20665             final String packageName = ps.pkg.packageName;
20666             // Skip over if system app
20667             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
20668                 continue;
20669             }
20670             if (DEBUG_CLEAN_APKS) {
20671                 Slog.i(TAG, "Checking package " + packageName);
20672             }
20673             boolean keep = shouldKeepUninstalledPackageLPr(packageName);
20674             if (keep) {
20675                 if (DEBUG_CLEAN_APKS) {
20676                     Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
20677                 }
20678             } else {
20679                 for (int i = 0; i < users.length; i++) {
20680                     if (users[i] != userHandle && ps.getInstalled(users[i])) {
20681                         keep = true;
20682                         if (DEBUG_CLEAN_APKS) {
20683                             Slog.i(TAG, "  Keeping package " + packageName + " for user "
20684                                     + users[i]);
20685                         }
20686                         break;
20687                     }
20688                 }
20689             }
20690             if (!keep) {
20691                 if (DEBUG_CLEAN_APKS) {
20692                     Slog.i(TAG, "  Removing package " + packageName);
20693                 }
20694                 mHandler.post(new Runnable() {
20695                     public void run() {
20696                         deletePackageX(packageName, userHandle, 0);
20697                     } //end run
20698                 });
20699             }
20700         }
20701     }
20702
20703     /** Called by UserManagerService */
20704     void createNewUser(int userId) {
20705         synchronized (mInstallLock) {
20706             mSettings.createNewUserLI(this, mInstaller, userId);
20707         }
20708         synchronized (mPackages) {
20709             scheduleWritePackageRestrictionsLocked(userId);
20710             scheduleWritePackageListLocked(userId);
20711             applyFactoryDefaultBrowserLPw(userId);
20712             primeDomainVerificationsLPw(userId);
20713         }
20714     }
20715
20716     void onNewUserCreated(final int userId) {
20717         mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20718         // If permission review for legacy apps is required, we represent
20719         // dagerous permissions for such apps as always granted runtime
20720         // permissions to keep per user flag state whether review is needed.
20721         // Hence, if a new user is added we have to propagate dangerous
20722         // permission grants for these legacy apps.
20723         if (Build.PERMISSIONS_REVIEW_REQUIRED) {
20724             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
20725                     | UPDATE_PERMISSIONS_REPLACE_ALL);
20726         }
20727     }
20728
20729     @Override
20730     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
20731         mContext.enforceCallingOrSelfPermission(
20732                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
20733                 "Only package verification agents can read the verifier device identity");
20734
20735         synchronized (mPackages) {
20736             return mSettings.getVerifierDeviceIdentityLPw();
20737         }
20738     }
20739
20740     @Override
20741     public void setPermissionEnforced(String permission, boolean enforced) {
20742         // TODO: Now that we no longer change GID for storage, this should to away.
20743         mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
20744                 "setPermissionEnforced");
20745         if (READ_EXTERNAL_STORAGE.equals(permission)) {
20746             synchronized (mPackages) {
20747                 if (mSettings.mReadExternalStorageEnforced == null
20748                         || mSettings.mReadExternalStorageEnforced != enforced) {
20749                     mSettings.mReadExternalStorageEnforced = enforced;
20750                     mSettings.writeLPr();
20751                 }
20752             }
20753             // kill any non-foreground processes so we restart them and
20754             // grant/revoke the GID.
20755             final IActivityManager am = ActivityManagerNative.getDefault();
20756             if (am != null) {
20757                 final long token = Binder.clearCallingIdentity();
20758                 try {
20759                     am.killProcessesBelowForeground("setPermissionEnforcement");
20760                 } catch (RemoteException e) {
20761                 } finally {
20762                     Binder.restoreCallingIdentity(token);
20763                 }
20764             }
20765         } else {
20766             throw new IllegalArgumentException("No selective enforcement for " + permission);
20767         }
20768     }
20769
20770     @Override
20771     @Deprecated
20772     public boolean isPermissionEnforced(String permission) {
20773         return true;
20774     }
20775
20776     @Override
20777     public boolean isStorageLow() {
20778         final long token = Binder.clearCallingIdentity();
20779         try {
20780             final DeviceStorageMonitorInternal
20781                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
20782             if (dsm != null) {
20783                 return dsm.isMemoryLow();
20784             } else {
20785                 return false;
20786             }
20787         } finally {
20788             Binder.restoreCallingIdentity(token);
20789         }
20790     }
20791
20792     @Override
20793     public IPackageInstaller getPackageInstaller() {
20794         return mInstallerService;
20795     }
20796
20797     private boolean userNeedsBadging(int userId) {
20798         int index = mUserNeedsBadging.indexOfKey(userId);
20799         if (index < 0) {
20800             final UserInfo userInfo;
20801             final long token = Binder.clearCallingIdentity();
20802             try {
20803                 userInfo = sUserManager.getUserInfo(userId);
20804             } finally {
20805                 Binder.restoreCallingIdentity(token);
20806             }
20807             final boolean b;
20808             if (userInfo != null && userInfo.isManagedProfile()) {
20809                 b = true;
20810             } else {
20811                 b = false;
20812             }
20813             mUserNeedsBadging.put(userId, b);
20814             return b;
20815         }
20816         return mUserNeedsBadging.valueAt(index);
20817     }
20818
20819     @Override
20820     public KeySet getKeySetByAlias(String packageName, String alias) {
20821         if (packageName == null || alias == null) {
20822             return null;
20823         }
20824         synchronized(mPackages) {
20825             final PackageParser.Package pkg = mPackages.get(packageName);
20826             if (pkg == null) {
20827                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20828                 throw new IllegalArgumentException("Unknown package: " + packageName);
20829             }
20830             KeySetManagerService ksms = mSettings.mKeySetManagerService;
20831             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
20832         }
20833     }
20834
20835     @Override
20836     public KeySet getSigningKeySet(String packageName) {
20837         if (packageName == null) {
20838             return null;
20839         }
20840         synchronized(mPackages) {
20841             final PackageParser.Package pkg = mPackages.get(packageName);
20842             if (pkg == null) {
20843                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20844                 throw new IllegalArgumentException("Unknown package: " + packageName);
20845             }
20846             if (pkg.applicationInfo.uid != Binder.getCallingUid()
20847                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
20848                 throw new SecurityException("May not access signing KeySet of other apps.");
20849             }
20850             KeySetManagerService ksms = mSettings.mKeySetManagerService;
20851             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
20852         }
20853     }
20854
20855     @Override
20856     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
20857         if (packageName == null || ks == null) {
20858             return false;
20859         }
20860         synchronized(mPackages) {
20861             final PackageParser.Package pkg = mPackages.get(packageName);
20862             if (pkg == null) {
20863                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20864                 throw new IllegalArgumentException("Unknown package: " + packageName);
20865             }
20866             IBinder ksh = ks.getToken();
20867             if (ksh instanceof KeySetHandle) {
20868                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
20869                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
20870             }
20871             return false;
20872         }
20873     }
20874
20875     @Override
20876     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
20877         if (packageName == null || ks == null) {
20878             return false;
20879         }
20880         synchronized(mPackages) {
20881             final PackageParser.Package pkg = mPackages.get(packageName);
20882             if (pkg == null) {
20883                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20884                 throw new IllegalArgumentException("Unknown package: " + packageName);
20885             }
20886             IBinder ksh = ks.getToken();
20887             if (ksh instanceof KeySetHandle) {
20888                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
20889                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
20890             }
20891             return false;
20892         }
20893     }
20894
20895     private void deletePackageIfUnusedLPr(final String packageName) {
20896         PackageSetting ps = mSettings.mPackages.get(packageName);
20897         if (ps == null) {
20898             return;
20899         }
20900         if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
20901             // TODO Implement atomic delete if package is unused
20902             // It is currently possible that the package will be deleted even if it is installed
20903             // after this method returns.
20904             mHandler.post(new Runnable() {
20905                 public void run() {
20906                     deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
20907                 }
20908             });
20909         }
20910     }
20911
20912     /**
20913      * Check and throw if the given before/after packages would be considered a
20914      * downgrade.
20915      */
20916     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
20917             throws PackageManagerException {
20918         if (after.versionCode < before.mVersionCode) {
20919             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20920                     "Update version code " + after.versionCode + " is older than current "
20921                     + before.mVersionCode);
20922         } else if (after.versionCode == before.mVersionCode) {
20923             if (after.baseRevisionCode < before.baseRevisionCode) {
20924                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20925                         "Update base revision code " + after.baseRevisionCode
20926                         + " is older than current " + before.baseRevisionCode);
20927             }
20928
20929             if (!ArrayUtils.isEmpty(after.splitNames)) {
20930                 for (int i = 0; i < after.splitNames.length; i++) {
20931                     final String splitName = after.splitNames[i];
20932                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
20933                     if (j != -1) {
20934                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
20935                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20936                                     "Update split " + splitName + " revision code "
20937                                     + after.splitRevisionCodes[i] + " is older than current "
20938                                     + before.splitRevisionCodes[j]);
20939                         }
20940                     }
20941                 }
20942             }
20943         }
20944     }
20945
20946     private static class MoveCallbacks extends Handler {
20947         private static final int MSG_CREATED = 1;
20948         private static final int MSG_STATUS_CHANGED = 2;
20949
20950         private final RemoteCallbackList<IPackageMoveObserver>
20951                 mCallbacks = new RemoteCallbackList<>();
20952
20953         private final SparseIntArray mLastStatus = new SparseIntArray();
20954
20955         public MoveCallbacks(Looper looper) {
20956             super(looper);
20957         }
20958
20959         public void register(IPackageMoveObserver callback) {
20960             mCallbacks.register(callback);
20961         }
20962
20963         public void unregister(IPackageMoveObserver callback) {
20964             mCallbacks.unregister(callback);
20965         }
20966
20967         @Override
20968         public void handleMessage(Message msg) {
20969             final SomeArgs args = (SomeArgs) msg.obj;
20970             final int n = mCallbacks.beginBroadcast();
20971             for (int i = 0; i < n; i++) {
20972                 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
20973                 try {
20974                     invokeCallback(callback, msg.what, args);
20975                 } catch (RemoteException ignored) {
20976                 }
20977             }
20978             mCallbacks.finishBroadcast();
20979             args.recycle();
20980         }
20981
20982         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
20983                 throws RemoteException {
20984             switch (what) {
20985                 case MSG_CREATED: {
20986                     callback.onCreated(args.argi1, (Bundle) args.arg2);
20987                     break;
20988                 }
20989                 case MSG_STATUS_CHANGED: {
20990                     callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
20991                     break;
20992                 }
20993             }
20994         }
20995
20996         private void notifyCreated(int moveId, Bundle extras) {
20997             Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
20998
20999             final SomeArgs args = SomeArgs.obtain();
21000             args.argi1 = moveId;
21001             args.arg2 = extras;
21002             obtainMessage(MSG_CREATED, args).sendToTarget();
21003         }
21004
21005         private void notifyStatusChanged(int moveId, int status) {
21006             notifyStatusChanged(moveId, status, -1);
21007         }
21008
21009         private void notifyStatusChanged(int moveId, int status, long estMillis) {
21010             Slog.v(TAG, "Move " + moveId + " status " + status);
21011
21012             final SomeArgs args = SomeArgs.obtain();
21013             args.argi1 = moveId;
21014             args.argi2 = status;
21015             args.arg3 = estMillis;
21016             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
21017
21018             synchronized (mLastStatus) {
21019                 mLastStatus.put(moveId, status);
21020             }
21021         }
21022     }
21023
21024     private final static class OnPermissionChangeListeners extends Handler {
21025         private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
21026
21027         private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
21028                 new RemoteCallbackList<>();
21029
21030         public OnPermissionChangeListeners(Looper looper) {
21031             super(looper);
21032         }
21033
21034         @Override
21035         public void handleMessage(Message msg) {
21036             switch (msg.what) {
21037                 case MSG_ON_PERMISSIONS_CHANGED: {
21038                     final int uid = msg.arg1;
21039                     handleOnPermissionsChanged(uid);
21040                 } break;
21041             }
21042         }
21043
21044         public void addListenerLocked(IOnPermissionsChangeListener listener) {
21045             mPermissionListeners.register(listener);
21046
21047         }
21048
21049         public void removeListenerLocked(IOnPermissionsChangeListener listener) {
21050             mPermissionListeners.unregister(listener);
21051         }
21052
21053         public void onPermissionsChanged(int uid) {
21054             if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
21055                 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
21056             }
21057         }
21058
21059         private void handleOnPermissionsChanged(int uid) {
21060             final int count = mPermissionListeners.beginBroadcast();
21061             try {
21062                 for (int i = 0; i < count; i++) {
21063                     IOnPermissionsChangeListener callback = mPermissionListeners
21064                             .getBroadcastItem(i);
21065                     try {
21066                         callback.onPermissionsChanged(uid);
21067                     } catch (RemoteException e) {
21068                         Log.e(TAG, "Permission listener is dead", e);
21069                     }
21070                 }
21071             } finally {
21072                 mPermissionListeners.finishBroadcast();
21073             }
21074         }
21075     }
21076
21077     private class PackageManagerInternalImpl extends PackageManagerInternal {
21078         @Override
21079         public void setLocationPackagesProvider(PackagesProvider provider) {
21080             synchronized (mPackages) {
21081                 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
21082             }
21083         }
21084
21085         @Override
21086         public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
21087             synchronized (mPackages) {
21088                 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
21089             }
21090         }
21091
21092         @Override
21093         public void setSmsAppPackagesProvider(PackagesProvider provider) {
21094             synchronized (mPackages) {
21095                 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
21096             }
21097         }
21098
21099         @Override
21100         public void setDialerAppPackagesProvider(PackagesProvider provider) {
21101             synchronized (mPackages) {
21102                 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
21103             }
21104         }
21105
21106         @Override
21107         public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
21108             synchronized (mPackages) {
21109                 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
21110             }
21111         }
21112
21113         @Override
21114         public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
21115             synchronized (mPackages) {
21116                 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
21117             }
21118         }
21119
21120         @Override
21121         public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
21122             synchronized (mPackages) {
21123                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
21124                         packageName, userId);
21125             }
21126         }
21127
21128         @Override
21129         public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
21130             synchronized (mPackages) {
21131                 mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
21132                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
21133                         packageName, userId);
21134             }
21135         }
21136
21137         @Override
21138         public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
21139             synchronized (mPackages) {
21140                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
21141                         packageName, userId);
21142             }
21143         }
21144
21145         @Override
21146         public void setKeepUninstalledPackages(final List<String> packageList) {
21147             Preconditions.checkNotNull(packageList);
21148             List<String> removedFromList = null;
21149             synchronized (mPackages) {
21150                 if (mKeepUninstalledPackages != null) {
21151                     final int packagesCount = mKeepUninstalledPackages.size();
21152                     for (int i = 0; i < packagesCount; i++) {
21153                         String oldPackage = mKeepUninstalledPackages.get(i);
21154                         if (packageList != null && packageList.contains(oldPackage)) {
21155                             continue;
21156                         }
21157                         if (removedFromList == null) {
21158                             removedFromList = new ArrayList<>();
21159                         }
21160                         removedFromList.add(oldPackage);
21161                     }
21162                 }
21163                 mKeepUninstalledPackages = new ArrayList<>(packageList);
21164                 if (removedFromList != null) {
21165                     final int removedCount = removedFromList.size();
21166                     for (int i = 0; i < removedCount; i++) {
21167                         deletePackageIfUnusedLPr(removedFromList.get(i));
21168                     }
21169                 }
21170             }
21171         }
21172
21173         @Override
21174         public boolean isPermissionsReviewRequired(String packageName, int userId) {
21175             synchronized (mPackages) {
21176                 // If we do not support permission review, done.
21177                 if (!Build.PERMISSIONS_REVIEW_REQUIRED) {
21178                     return false;
21179                 }
21180
21181                 PackageSetting packageSetting = mSettings.mPackages.get(packageName);
21182                 if (packageSetting == null) {
21183                     return false;
21184                 }
21185
21186                 // Permission review applies only to apps not supporting the new permission model.
21187                 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
21188                     return false;
21189                 }
21190
21191                 // Legacy apps have the permission and get user consent on launch.
21192                 PermissionsState permissionsState = packageSetting.getPermissionsState();
21193                 return permissionsState.isPermissionReviewRequired(userId);
21194             }
21195         }
21196
21197         @Override
21198         public ApplicationInfo getApplicationInfo(String packageName, int userId) {
21199             return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
21200         }
21201
21202         @Override
21203         public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21204                 int userId) {
21205             return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
21206         }
21207
21208         @Override
21209         public void setDeviceAndProfileOwnerPackages(
21210                 int deviceOwnerUserId, String deviceOwnerPackage,
21211                 SparseArray<String> profileOwnerPackages) {
21212             mProtectedPackages.setDeviceAndProfileOwnerPackages(
21213                     deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
21214         }
21215
21216         @Override
21217         public boolean isPackageDataProtected(int userId, String packageName) {
21218             return mProtectedPackages.isPackageDataProtected(userId, packageName);
21219         }
21220
21221         @Override
21222         public boolean wasPackageEverLaunched(String packageName, int userId) {
21223             synchronized (mPackages) {
21224                 return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
21225             }
21226         }
21227     }
21228
21229     @Override
21230     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
21231         enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
21232         synchronized (mPackages) {
21233             final long identity = Binder.clearCallingIdentity();
21234             try {
21235                 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
21236                         packageNames, userId);
21237             } finally {
21238                 Binder.restoreCallingIdentity(identity);
21239             }
21240         }
21241     }
21242
21243     private static void enforceSystemOrPhoneCaller(String tag) {
21244         int callingUid = Binder.getCallingUid();
21245         if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
21246             throw new SecurityException(
21247                     "Cannot call " + tag + " from UID " + callingUid);
21248         }
21249     }
21250
21251     boolean isHistoricalPackageUsageAvailable() {
21252         return mPackageUsage.isHistoricalPackageUsageAvailable();
21253     }
21254
21255     /**
21256      * Return a <b>copy</b> of the collection of packages known to the package manager.
21257      * @return A copy of the values of mPackages.
21258      */
21259     Collection<PackageParser.Package> getPackages() {
21260         synchronized (mPackages) {
21261             return new ArrayList<>(mPackages.values());
21262         }
21263     }
21264
21265     /**
21266      * Logs process start information (including base APK hash) to the security log.
21267      * @hide
21268      */
21269     public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
21270             String apkFile, int pid) {
21271         if (!SecurityLog.isLoggingEnabled()) {
21272             return;
21273         }
21274         Bundle data = new Bundle();
21275         data.putLong("startTimestamp", System.currentTimeMillis());
21276         data.putString("processName", processName);
21277         data.putInt("uid", uid);
21278         data.putString("seinfo", seinfo);
21279         data.putString("apkFile", apkFile);
21280         data.putInt("pid", pid);
21281         Message msg = mProcessLoggingHandler.obtainMessage(
21282                 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
21283         msg.setData(data);
21284         mProcessLoggingHandler.sendMessage(msg);
21285     }
21286
21287     public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
21288         return mCompilerStats.getPackageStats(pkgName);
21289     }
21290
21291     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
21292         return getOrCreateCompilerPackageStats(pkg.packageName);
21293     }
21294
21295     public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
21296         return mCompilerStats.getOrCreatePackageStats(pkgName);
21297     }
21298
21299     public void deleteCompilerPackageStats(String pkgName) {
21300         mCompilerStats.deletePackageStats(pkgName);
21301     }
21302 }